For proto_tree_add_item(..., proto_xxx, ...)use ENC_NA as the encoding arg.
[obnox/wireshark/wip.git] / epan / dissectors / packet-umts_fp.c
index 46b2fdcb7cbcc7ddaa4d7411198ba3611708b0c0..230ed444e0c4c83f817802970a91769ca8ddbbd7 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <epan/packet.h>
 #include <epan/expert.h>
+#include <epan/prefs.h>
 
 #include "packet-umts_fp.h"
 
  * TODO:
  *  - IUR interface-specific formats
  *  - verify header & payload CRCs
+ *  - do CRC verification before further parsing
  */
 
 /* Initialize the protocol and registered fields. */
 int proto_fp = -1;
 
+static int hf_fp_release = -1;
+static int hf_fp_release_version = -1;
+static int hf_fp_release_year = -1;
+static int hf_fp_release_month = -1;
 static int hf_fp_channel_type = -1;
 static int hf_fp_division = -1;
 static int hf_fp_direction = -1;
+static int hf_fp_ddi_config = -1;
+static int hf_fp_ddi_config_ddi = -1;
+static int hf_fp_ddi_config_macd_pdu_size = -1;
+
 static int hf_fp_header_crc = -1;
 static int hf_fp_ft = -1;
 static int hf_fp_cfn = -1;
@@ -86,6 +96,20 @@ 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_e_rnti = -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;
@@ -113,6 +137,7 @@ static int hf_fp_hsdsch_data_padding = -1;
 static int hf_fp_hsdsch_new_ie_flags = -1;
 static int hf_fp_hsdsch_new_ie_flag[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
 static int hf_fp_hsdsch_drt = -1;
+static int hf_fp_hsdsch_entity = -1;
 static int hf_fp_timing_advance = -1;
 static int hf_fp_num_of_pdu = -1;
 static int hf_fp_mac_d_pdu_len = -1;
@@ -159,17 +184,35 @@ static int hf_fp_spare_extension = -1;
 
 /* Subtrees. */
 static int ett_fp = -1;
+static int ett_fp_release = -1;
 static int ett_fp_data = -1;
 static int ett_fp_crcis = -1;
+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;
 
+static dissector_handle_t mac_fdd_dch_handle;
+static dissector_handle_t mac_fdd_rach_handle;
+static dissector_handle_t mac_fdd_fach_handle;
+static dissector_handle_t mac_fdd_pch_handle;
+static dissector_handle_t mac_fdd_edch_handle;
+static dissector_handle_t mac_fdd_hsdsch_handle;
+
+static proto_tree *top_level_tree = NULL;
+
+/* Variables used for preferences */
+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;
@@ -177,6 +220,16 @@ 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[] =
 {
@@ -198,6 +251,9 @@ static const value_string channel_type_vals[] =
     { CHANNEL_IUR_DSCH,     "IUR DSCH" },
     { CHANNEL_EDCH,         "EDCH" },
     { CHANNEL_RACH_TDD_128, "RACH_TDD_128" },
+    { CHANNEL_HSDSCH_COMMON,"HSDSCH-COMMON" },
+    { CHANNEL_HSDSCH_COMMON_T3,"HSDSCH-COMMON-T3" },
+    { CHANNEL_EDCH_COMMON,     "EDCH-COMMON"},
     { 0, NULL }
 };
 
@@ -257,9 +313,44 @@ static const value_string congestion_status_vals[] = {
 static const value_string e_rucch_flag_vals[] = {
     { 0,   "Conventional E-RUCCH reception" },
     { 1,   "TA Request reception" },
-    { 0,   NULL },
+    { 0,   NULL }
+};
+
+static const value_string hsdshc_mac_entity_vals[] = {
+    { entity_not_specified,    "Unspecified (assume MAC-hs)" },
+    { hs,                      "MAC-hs" },
+    { ehs,                     "MAC-ehs" },
+    { 0,   NULL }
 };
 
+/* TODO: add and use */
+static const value_string segmentation_status_vals[] = {
+    { 0,    "" },
+    { 1,    "" },
+    { 2,    "" },
+    { 3,    "" },
+    { 0,   NULL }
+};
+
+static const value_string lchid_vals[] = {
+    { 0,    "Logical Channel 1" },
+    { 1,    "Logical Channel 2" },
+    { 2,    "Logical Channel 3" },
+    { 3,    "Logical Channel 4" },
+    { 4,    "Logical Channel 5" },
+    { 5,    "Logical Channel 6" },
+    { 6,    "Logical Channel 7" },
+    { 7,    "Logical Channel 8" },
+    { 8,    "Logical Channel 9" },
+    { 9,    "Logical Channel 10" },
+    { 10,   "Logical Channel 11" },
+    { 11,   "Logical Channel 12" },
+    { 12,   "Logical Channel 13" },
+    { 13,   "Logical Channel 14" },
+    { 14,   "CCCH (SRB0)" },
+    { 15,   "E-RNTI being included (FDD only)" },
+    { 0,   NULL }
+};
 
 /* Dedicated control types */
 #define DCH_OUTER_LOOP_POWER_CONTROL            1
@@ -295,7 +386,7 @@ static const value_string dch_control_frame_type_vals[] = {
 #define COMMON_TIMING_ADJUSTMENT                       2
 #define COMMON_DL_SYNCHRONISATION                      3
 #define COMMON_UL_SYNCHRONISATION                      4
-                                                       
+
 #define COMMON_DL_NODE_SYNCHRONISATION                 6
 #define COMMON_UL_NODE_SYNCHRONISATION                 7
 #define COMMON_DYNAMIC_PUSCH_ASSIGNMENT                8
@@ -322,13 +413,15 @@ static const value_string common_control_frame_type_vals[] = {
 
 /* Dissect message parts */
 static int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                           int offset, struct fp_info *p_fp_info, int *num_tbs);
+                           int offset, struct fp_info *p_fp_info,
+                           dissector_handle_t *data_handle);
 static int dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                  int offset, guint16 length, guint16 number_of_pdus);
 static int dissect_macd_pdu_data_type_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                         int offset, guint16 length, guint16 number_of_pdus);
+
 static int dissect_crci_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                             int num_tbs, int offset);
+                             fp_info *p_fp_info, int offset);
 static void dissect_spare_extension_and_crc(tvbuff_t *tvb, packet_info *pinfo,
                                             proto_tree *tree, guint8 dch_crc_present,
                                             int offset);
@@ -342,10 +435,10 @@ static int dissect_common_dl_node_synchronisation(packet_info *pinfo, proto_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,
+static int dissect_common_dl_synchronisation(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,
+static int dissect_common_ul_synchronisation(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,
@@ -378,7 +471,7 @@ static void dissect_cpch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_t
 static void dissect_bch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                      int offset, struct fp_info *p_fp_info);
 static void dissect_iur_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                                          int offset, struct fp_info *p_fp_info _U_);
+                                          int offset, struct fp_info *p_fp_info);
 static void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                         int offset, struct fp_info *p_fp_info);
 static void dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
@@ -418,7 +511,13 @@ 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,
+                                       gboolean is_common);
+
+static void dissect_e_dch_t2_or_common_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                                                    int offset, struct fp_info *p_fp_info,
+                                                    int number_of_subframes,
+                                                    gboolean is_common);
 
 /* Main dissection function */
 static void dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
@@ -428,22 +527,31 @@ void proto_register_fp(void);
 void proto_reg_handoff_fp(void);
 
 
-
+static int get_tb_count(struct fp_info *p_fp_info)
+{
+    int chan, tb_count = 0;
+    for (chan = 0; chan < p_fp_info->num_chans; chan++) {
+        tb_count += p_fp_info->chan_num_tbs[chan];
+    }
+    return tb_count;
+}
 
 /* Dissect the TBs of a data frame */
-int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                    int offset, struct fp_info *p_fp_info, int *num_tbs)
+static int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                           int offset, struct fp_info *p_fp_info,
+                           dissector_handle_t *data_handle)
 {
-    int chan;
+    int chan, num_tbs = 0;
     int bit_offset = 0;
     guint data_bits = 0;
     proto_item *tree_ti = NULL;
     proto_tree *data_tree = NULL;
+    gboolean dissected = FALSE;
 
     if (tree)
     {
         /* Add data subtree */
-        tree_ti =  proto_tree_add_item(tree, hf_fp_data, tvb, offset, -1, FALSE);
+        tree_ti =  proto_tree_add_item(tree, hf_fp_data, tvb, offset, -1, ENC_NA);
         proto_item_set_text(tree_ti, "TB data for %u chans", p_fp_info->num_chans);
         data_tree = proto_item_add_subtree(tree_ti, ett_fp_data);
     }
@@ -465,6 +573,7 @@ int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
         }
 
         /* Show TBs from non-empty channels */
+        pinfo->fd->subnum = chan; /* set subframe number to current TB */
         for (n=0; n < p_fp_info->chan_num_tbs[chan]; n++)
         {
             proto_item *ti;
@@ -473,11 +582,20 @@ int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                 ti = proto_tree_add_item(data_tree, hf_fp_tb, tvb,
                                          offset + (bit_offset/8),
                                          ((bit_offset % 8) + p_fp_info->chan_tf_size[chan] + 7) / 8,
-                                         FALSE);
+                                         ENC_NA);
                 proto_item_set_text(ti, "TB (chan %u, tb %u, %u bits)",
                                     chan+1, n+1, p_fp_info->chan_tf_size[chan]);
             }
-            (*num_tbs)++;
+                       if (preferences_call_mac_dissectors && data_handle &&
+                               p_fp_info->chan_tf_size[chan] > 0) {
+                tvbuff_t *next_tvb;
+                                       next_tvb = tvb_new_subset(tvb, offset + bit_offset/8,
+                                                       ((bit_offset % 8) + p_fp_info->chan_tf_size[chan] + 7) / 8, -1);
+                                       /* TODO: maybe this decision can be based only on info available in fp_info */
+                                       call_dissector(*data_handle, next_tvb, pinfo, top_level_tree);
+                                       dissected = TRUE;
+                       }
+            num_tbs++;
 
             /* Advance bit offset */
             bit_offset += p_fp_info->chan_tf_size[chan];
@@ -491,17 +609,15 @@ int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
         }
     }
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
+    if (dissected == FALSE) {
         col_append_fstr(pinfo->cinfo, COL_INFO, "(%u bits in %u tbs)",
-                        data_bits, *num_tbs);
+                        data_bits, num_tbs);
     }
 
     /* Data tree should cover entire length */
-    if (data_tree)
-    {
+    if (data_tree) {
         proto_item_set_len(tree_ti, bit_offset/8);
-        proto_item_append_text(tree_ti, " (%u bits in %u tbs)", data_bits, *num_tbs);
+        proto_item_append_text(tree_ti, " (%u bits in %u tbs)", data_bits, num_tbs);
     }
 
     /* Move offset past TBs (we know its already padded out to next byte) */
@@ -513,43 +629,49 @@ int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
 /* Dissect the MAC-d PDUs of an HS-DSCH (type 1) frame.
    Length is in bits, and payload is offset by 4 bits of padding */
-int dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                          int offset, guint16 length, guint16 number_of_pdus)
+static int dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                                 int offset, guint16 length, guint16 number_of_pdus)
 {
     int pdu;
     int bit_offset = 0;
     proto_item *pdus_ti = NULL;
     proto_tree *data_tree = NULL;
+    gboolean dissected = FALSE;
 
     /* Add data subtree */
     if (tree)
     {
-        pdus_ti =  proto_tree_add_item(tree, hf_fp_data, tvb, offset, -1, FALSE);
+        pdus_ti =  proto_tree_add_item(tree, hf_fp_data, tvb, offset, -1, ENC_NA);
         proto_item_set_text(pdus_ti, "%u MAC-d PDUs of %u bits", number_of_pdus, length);
         data_tree = proto_item_add_subtree(pdus_ti, ett_fp_data);
     }
 
     /* Now for the PDUs */
-    for (pdu=0; pdu < number_of_pdus; pdu++)
-    {
+    for (pdu=0; pdu < number_of_pdus; pdu++) {
         proto_item *pdu_ti;
 
-        if (data_tree)
-        {
+        if (data_tree) {
             /* Show 4 bits padding at start of PDU */
-            proto_tree_add_item(data_tree, hf_fp_hsdsch_data_padding, tvb, offset+(bit_offset/8), 1, FALSE);
+            proto_tree_add_item(data_tree, hf_fp_hsdsch_data_padding, tvb, offset+(bit_offset/8), 1, ENC_BIG_ENDIAN);
         }
         bit_offset += 4;
 
         /* Data bytes! */
-        if (data_tree)
-        {
+        if (data_tree) {
+            pinfo->fd->subnum = pdu; /* set subframe number to current TB */
             pdu_ti = proto_tree_add_item(data_tree, hf_fp_mac_d_pdu, tvb,
                                          offset + (bit_offset/8),
                                          ((bit_offset % 8) + length + 7) / 8,
-                                         FALSE);
+                                         ENC_NA);
             proto_item_set_text(pdu_ti, "MAC-d PDU (PDU %u)", pdu+1);
         }
+               if (preferences_call_mac_dissectors) {
+            tvbuff_t *next_tvb;
+                       next_tvb = tvb_new_subset(tvb, offset + bit_offset/8,
+                               ((bit_offset % 8) + length + 7)/8, -1);
+                       call_dissector(mac_fdd_hsdsch_handle, next_tvb, pinfo, top_level_tree);
+                       dissected = TRUE;
+               }
 
         /* Advance bit offset */
         bit_offset += length;
@@ -568,8 +690,7 @@ int dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
     offset += (bit_offset / 8);
 
     /* Show summary in info column */
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
+    if (dissected == FALSE) {
         col_append_fstr(pinfo->cinfo, COL_INFO, "   %u PDUs of %u bits",
                         number_of_pdus, length);
     }
@@ -580,18 +701,19 @@ int dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
 /* Dissect the MAC-d PDUs of an HS-DSCH (type 2) frame.
    Length is in bytes, and payload is byte-aligned (no padding) */
-int dissect_macd_pdu_data_type_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                                 int offset, guint16 length, guint16 number_of_pdus)
+static int dissect_macd_pdu_data_type_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                                        int offset, guint16 length, guint16 number_of_pdus)
 {
     int pdu;
     proto_item *pdus_ti = NULL;
     proto_tree *data_tree = NULL;
     int first_offset = offset;
+    gboolean dissected = FALSE;
 
     /* Add data subtree */
     if (tree)
     {
-        pdus_ti =  proto_tree_add_item(tree, hf_fp_data, tvb, offset, -1, FALSE);
+        pdus_ti =  proto_tree_add_item(tree, hf_fp_data, tvb, offset, -1, ENC_NA);
         proto_item_set_text(pdus_ti, "%u MAC-d PDUs of %u bytes", number_of_pdus, length);
         data_tree = proto_item_add_subtree(pdus_ti, ett_fp_data);
     }
@@ -605,8 +727,13 @@ int dissect_macd_pdu_data_type_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
         if (data_tree)
         {
             pdu_ti = proto_tree_add_item(data_tree, hf_fp_mac_d_pdu, tvb,
-                                         offset, length, FALSE);
+                                         offset, length, ENC_NA);
             proto_item_set_text(pdu_ti, "MAC-d PDU (PDU %u)", pdu+1);
+            if (preferences_call_mac_dissectors) {
+                tvbuff_t *next_tvb = tvb_new_subset(tvb, offset, length, -1);
+                call_dissector(mac_fdd_hsdsch_handle, next_tvb, pinfo, top_level_tree);
+                dissected = TRUE;
+            }
         }
 
         /* Advance offset */
@@ -617,8 +744,7 @@ int dissect_macd_pdu_data_type_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
     proto_item_set_len(pdus_ti, offset-first_offset);
 
     /* Show summary in info column */
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
+    if (!dissected) {
         col_append_fstr(pinfo->cinfo, COL_INFO, "   %u PDUs of %u bits",
                         number_of_pdus, length*8);
     }
@@ -626,21 +752,21 @@ int dissect_macd_pdu_data_type_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
     return offset;
 }
 
-
-
 /* Dissect CRCI bits (uplink) */
-int dissect_crci_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                      int num_tbs, int offset)
+static int dissect_crci_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                             fp_info *p_fp_info, int offset)
 {
-    int n;
+    int n, num_tbs;
     proto_item *ti = NULL;
     proto_tree *crcis_tree = NULL;
     guint errors = 0;
 
+    num_tbs = get_tb_count(p_fp_info);
+
     /* Add CRCIs subtree */
     if (tree)
     {
-        ti =  proto_tree_add_item(tree, hf_fp_crcis, tvb, offset, (num_tbs+7)/8, FALSE);
+        ti =  proto_tree_add_item(tree, hf_fp_crcis, tvb, offset, (num_tbs+7)/8, ENC_NA);
         proto_item_set_text(ti, "CRCI bits for %u tbs", num_tbs);
         crcis_tree = proto_item_add_subtree(ti, ett_fp_crcis);
     }
@@ -650,7 +776,7 @@ int dissect_crci_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
     {
         int bit = (tvb_get_guint8(tvb, offset+(n/8)) >> (7-(n%8))) & 0x01;
         proto_tree_add_item(crcis_tree, hf_fp_crci[n%8], tvb, offset+(n/8),
-                            1, FALSE);
+                            1, ENC_BIG_ENDIAN);
 
         if (bit == 1)
         {
@@ -675,9 +801,9 @@ 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)
+static 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);
@@ -692,7 +818,7 @@ void dissect_spare_extension_and_crc(tvbuff_t *tvb, packet_info *pinfo,
     if (remain > crc_size)
     {
         ti = proto_tree_add_item(tree, hf_fp_spare_extension, tvb,
-                                 offset, remain-crc_size, FALSE);
+                                 offset, remain-crc_size, ENC_NA);
         proto_item_append_text(ti, " (%u octets)", remain-crc_size);
         expert_add_info_format(pinfo, ti,
                                PI_UNDECODED, PI_WARN,
@@ -703,7 +829,7 @@ void dissect_spare_extension_and_crc(tvbuff_t *tvb, packet_info *pinfo,
     if (crc_size)
     {
         proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, crc_size,
-                            FALSE);
+                            ENC_BIG_ENDIAN);
     }
 }
 
@@ -729,18 +855,15 @@ int dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbuf
 
         /* CFN control */
         cfn = tvb_get_guint8(tvb, offset);
-        proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
         /* ToA */
         toa = tvb_get_ntohs(tvb, offset);
-        proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, FALSE);
+        proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, ENC_BIG_ENDIAN);
         offset += 2;
 
-        if (check_col(pinfo->cinfo, COL_INFO))
-        {
-            col_append_fstr(pinfo->cinfo, COL_INFO, "   CFN=%u, ToA=%d", cfn, toa);
-        }
+        col_append_fstr(pinfo->cinfo, COL_INFO, "   CFN=%u, ToA=%d", cfn, toa);
     }
     else
     {
@@ -749,7 +872,7 @@ int dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbuf
 
         /* PCH CFN is 12 bits */
         cfn = (tvb_get_ntohs(tvb, offset) >> 4);
-        proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, FALSE);
+        proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, ENC_BIG_ENDIAN);
         offset += 2;
 
         /* 4 bits of padding follow... */
@@ -759,61 +882,52 @@ int dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbuf
         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);
-        }
+        col_append_fstr(pinfo->cinfo, COL_INFO, "   CFN=%u, ToA=%d", cfn, toa);
     }
     return offset;
 }
 
-int dissect_common_dl_node_synchronisation(packet_info *pinfo, proto_tree *tree,
-                                           tvbuff_t *tvb, int offset)
+static int dissect_common_dl_node_synchronisation(packet_info *pinfo, proto_tree *tree,
+                                                  tvbuff_t *tvb, int offset)
 {
     /* T1 (3 bytes) */
     guint32 t1 = tvb_get_ntoh24(tvb, offset);
-    proto_tree_add_item(tree, hf_fp_t1, tvb, offset, 3, FALSE);
+    proto_tree_add_item(tree, hf_fp_t1, tvb, offset, 3, ENC_BIG_ENDIAN);
     offset += 3;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_fstr(pinfo->cinfo, COL_INFO, "   T1=%u", t1);
-    }
+    col_append_fstr(pinfo->cinfo, COL_INFO, "   T1=%u", t1);
 
     return offset;
 }
 
-int dissect_common_ul_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)
 {
     guint32 t1, t2, t3;
 
     /* T1 (3 bytes) */
     t1 = tvb_get_ntoh24(tvb, offset);
-    proto_tree_add_item(tree, hf_fp_t1, tvb, offset, 3, FALSE);
+    proto_tree_add_item(tree, hf_fp_t1, tvb, offset, 3, ENC_BIG_ENDIAN);
     offset += 3;
 
     /* T2 (3 bytes) */
     t2 = tvb_get_ntoh24(tvb, offset);
-    proto_tree_add_item(tree, hf_fp_t2, tvb, offset, 3, FALSE);
+    proto_tree_add_item(tree, hf_fp_t2, tvb, offset, 3, ENC_BIG_ENDIAN);
     offset += 3;
 
     /* T3 (3 bytes) */
     t3 = tvb_get_ntoh24(tvb, offset);
-    proto_tree_add_item(tree, hf_fp_t3, tvb, offset, 3, FALSE);
+    proto_tree_add_item(tree, hf_fp_t3, tvb, offset, 3, ENC_BIG_ENDIAN);
     offset += 3;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_fstr(pinfo->cinfo, COL_INFO, "   T1=%u T2=%u, T3=%u",
-                        t1, t2, t3);
-    }
+    col_append_fstr(pinfo->cinfo, COL_INFO, "   T1=%u T2=%u, T3=%u",
+                    t1, t2, t3);
 
     return offset;
 }
 
-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_dl_synchronisation(packet_info *pinfo, proto_tree *tree,
+                                             tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
 {
     guint16 cfn;
 
@@ -821,41 +935,38 @@ int 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);
+        proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
     }
     else
     {
         /* PCH CFN is 12 bits */
         cfn = (tvb_get_ntohs(tvb, offset) >> 4);
-        proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, FALSE);
+        proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, ENC_BIG_ENDIAN);
 
         /* 4 bits of padding follow... */
         offset += 2;
     }
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_fstr(pinfo->cinfo, COL_INFO, "   CFN=%u", cfn);
-    }
+    col_append_fstr(pinfo->cinfo, COL_INFO, "   CFN=%u", cfn);
 
     return offset;
 }
 
-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_ul_synchronisation(packet_info *pinfo, proto_tree *tree,
+                                             tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
 {
     return dissect_common_timing_adjustment(pinfo, tree, tvb, offset, p_fp_info);
 }
 
-int dissect_common_timing_advance(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+static int dissect_common_timing_advance(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
     guint8 cfn;
     guint16 timing_advance;
 
     /* CFN control */
     cfn = tvb_get_guint8(tvb, offset);
-    proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
     /* Timing Advance */
@@ -863,43 +974,37 @@ int dissect_common_timing_advance(packet_info *pinfo, proto_tree *tree, tvbuff_t
     proto_tree_add_uint(tree, hf_fp_timing_advance, tvb, offset, 1, timing_advance);
     offset++;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, TA = %u",
-                        cfn, timing_advance);
-    }
+    col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, TA = %u",
+                    cfn, timing_advance);
 
     return offset;
 }
 
-int dissect_hsdpa_capacity_request(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)
 {
     guint8 priority;
     guint16 user_buffer_size;
 
     /* CmCH-PI */
     priority = (tvb_get_guint8(tvb, offset) & 0x0f);
-    proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
     /* User buffer size */
     user_buffer_size = tvb_get_ntohs(tvb, offset);
-    proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, FALSE);
+    proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, ENC_BIG_ENDIAN);
     offset += 2;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_fstr(pinfo->cinfo, COL_INFO, "      CmCH-PI=%u  User-Buffer-Size=%u",
-                        priority, user_buffer_size);
-    }
+    col_append_fstr(pinfo->cinfo, COL_INFO, "      CmCH-PI=%u  User-Buffer-Size=%u",
+                    priority, user_buffer_size);
 
     return offset;
 }
 
-int dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
-                                      tvbuff_t *tvb, int offset,
-                                      struct fp_info *p_fp_info)
+static int dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
+                                             tvbuff_t *tvb, int offset,
+                                             struct fp_info *p_fp_info)
 {
     proto_item *ti;
     proto_item *rate_ti;
@@ -912,21 +1017,21 @@ int dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
     if ((p_fp_info->release == 6) || (p_fp_info->release == 7))
     {
         proto_tree_add_bits_item(tree, hf_fp_congestion_status, tvb,
-                                 offset*8 + 2, 2, FALSE);
+                                 offset*8 + 2, 2, ENC_BIG_ENDIAN);
     }
 
     /* CmCH-PI */
-    proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
     /* Max MAC-d PDU length (13 bits) */
     max_pdu_length = tvb_get_ntohs(tvb, offset) >> 3;
-    proto_tree_add_item(tree, hf_fp_hsdsch_max_macd_pdu_len, tvb, offset, 2, FALSE);
+    proto_tree_add_item(tree, hf_fp_hsdsch_max_macd_pdu_len, tvb, offset, 2, ENC_BIG_ENDIAN);
     offset++;
 
     /* HS-DSCH credits (11 bits) */
     ti = proto_tree_add_bits_ret_val(tree, hf_fp_hsdsch_credits, tvb,
-                                     offset*8 + 5, 11, &credits, FALSE);
+                                     offset*8 + 5, 11, &credits, ENC_BIG_ENDIAN);
     offset += 2;
 
     /* Interesting values */
@@ -953,7 +1058,7 @@ int dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
 
     /* HS-DSCH Repetition period */
     repetition_period = tvb_get_guint8(tvb, offset);
-    ti = proto_tree_add_item(tree, hf_fp_hsdsch_repetition_period, tvb, offset, 1, FALSE);
+    ti = proto_tree_add_item(tree, hf_fp_hsdsch_repetition_period, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
     if (repetition_period == 0)
     {
@@ -963,7 +1068,7 @@ int dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
     /* Calculated and show effective rate enabled */
     if (credits == 2047)
     {
-        rate_ti = proto_tree_add_item(tree, hf_fp_hsdsch_unlimited_rate, tvb, 0, 0, FALSE);
+        rate_ti = proto_tree_add_item(tree, hf_fp_hsdsch_unlimited_rate, tvb, 0, 0, ENC_NA);
         PROTO_ITEM_SET_GENERATED(rate_ti);
     }
     else
@@ -977,18 +1082,15 @@ int dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
         }
     }
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_fstr(pinfo->cinfo, COL_INFO,
-                        "   Max-PDU-len=%u  Credits=%u  Interval=%u  Rep-Period=%u",
-                        max_pdu_length, (guint16)credits, interval, repetition_period);
-    }
+    col_append_fstr(pinfo->cinfo, COL_INFO,
+                    "   Max-PDU-len=%u  Credits=%u  Interval=%u  Rep-Period=%u",
+                    max_pdu_length, (guint16)credits, interval, repetition_period);
 
     return offset;
 }
 
-int dissect_hsdpa_capacity_allocation_type_2(packet_info *pinfo, proto_tree *tree,
-                                             tvbuff_t *tvb, int offset)
+static int dissect_hsdpa_capacity_allocation_type_2(packet_info *pinfo, proto_tree *tree,
+                                                    tvbuff_t *tvb, int offset)
 {
     proto_item *ti;
     proto_item *rate_ti;
@@ -999,17 +1101,17 @@ int dissect_hsdpa_capacity_allocation_type_2(packet_info *pinfo, proto_tree *tre
 
     /* Congestion status */
     proto_tree_add_bits_item(tree, hf_fp_congestion_status, tvb,
-                            offset*8 + 2, 2, FALSE);
+                            offset*8 + 2, 2, ENC_BIG_ENDIAN);
 
     /* CmCH-PI */
-    proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
     /* 5 spare bits follow here */
 
     /* Max MAC-d/c PDU length (11 bits) */
     max_pdu_length = tvb_get_ntohs(tvb, offset) & 0x7ff;
-    proto_tree_add_item(tree, hf_fp_hsdsch_max_macdc_pdu_len, tvb, offset, 2, FALSE);
+    proto_tree_add_item(tree, hf_fp_hsdsch_max_macdc_pdu_len, tvb, offset, 2, ENC_BIG_ENDIAN);
     offset += 2;
 
     /* HS-DSCH credits (16 bits) */
@@ -1042,7 +1144,7 @@ int dissect_hsdpa_capacity_allocation_type_2(packet_info *pinfo, proto_tree *tre
 
     /* HS-DSCH Repetition period */
     repetition_period = tvb_get_guint8(tvb, offset);
-    ti = proto_tree_add_item(tree, hf_fp_hsdsch_repetition_period, tvb, offset, 1, FALSE);
+    ti = proto_tree_add_item(tree, hf_fp_hsdsch_repetition_period, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
     if (repetition_period == 0)
     {
@@ -1052,7 +1154,7 @@ int dissect_hsdpa_capacity_allocation_type_2(packet_info *pinfo, proto_tree *tre
     /* Calculated and show effective rate enabled */
     if (credits == 65535)
     {
-        rate_ti = proto_tree_add_item(tree, hf_fp_hsdsch_unlimited_rate, tvb, 0, 0, FALSE);
+        rate_ti = proto_tree_add_item(tree, hf_fp_hsdsch_unlimited_rate, tvb, 0, 0, ENC_NA);
         PROTO_ITEM_SET_GENERATED(rate_ti);
     }
     else
@@ -1065,20 +1167,17 @@ int dissect_hsdpa_capacity_allocation_type_2(packet_info *pinfo, proto_tree *tre
         }
     }
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_fstr(pinfo->cinfo, COL_INFO,
-                        "   Max-PDU-len=%u  Credits=%u  Interval=%u  Rep-Period=%u",
-                        max_pdu_length, credits, interval, repetition_period);
-    }
+    col_append_fstr(pinfo->cinfo, COL_INFO,
+                    "   Max-PDU-len=%u  Credits=%u  Interval=%u  Rep-Period=%u",
+                    max_pdu_length, credits, interval, repetition_period);
 
     return offset;
 }
 
 
 
-int 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)
 {
     guint8 pusch_set_id;
     guint8 activation_cfn;
@@ -1086,12 +1185,12 @@ int dissect_common_dynamic_pusch_assignment(packet_info *pinfo, proto_tree *tree
 
     /* PUSCH Set Id */
     pusch_set_id = tvb_get_guint8(tvb, offset);
-    proto_tree_add_item(tree, hf_fp_pusch_set_id, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_pusch_set_id, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
     /* Activation CFN */
     activation_cfn = tvb_get_guint8(tvb, offset);
-    proto_tree_add_item(tree, hf_fp_activation_cfn, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_activation_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
     /* Duration */
@@ -1099,12 +1198,9 @@ int dissect_common_dynamic_pusch_assignment(packet_info *pinfo, proto_tree *tree
     proto_tree_add_uint(tree, hf_fp_duration, tvb, offset, 1, duration);
     offset++;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_fstr(pinfo->cinfo, COL_INFO,
-                        "   PUSCH Set Id=%u  Activation CFN=%u  Duration=%u",
-                        pusch_set_id, activation_cfn, duration);
-    }
+    col_append_fstr(pinfo->cinfo, COL_INFO,
+                    "   PUSCH Set Id=%u  Activation CFN=%u  Duration=%u",
+                    pusch_set_id, activation_cfn, duration);
 
     return offset;
 }
@@ -1114,19 +1210,16 @@ int dissect_common_dynamic_pusch_assignment(packet_info *pinfo, proto_tree *tree
 
 
 /* Dissect the control part of a common channel message */
-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_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                                  int offset, struct fp_info *p_fp_info)
 {
     /* Common control frame type */
     guint8 control_frame_type = tvb_get_guint8(tvb, offset);
-    proto_tree_add_item(tree, hf_fp_common_control_frame_type, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_common_control_frame_type, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_str(pinfo->cinfo, COL_INFO,
-                       val_to_str(control_frame_type, common_control_frame_type_vals, "Unknown"));
-    }
+    col_append_str(pinfo->cinfo, COL_INFO,
+                   val_to_str_const(control_frame_type, common_control_frame_type_vals, "Unknown"));
 
     /* Frame-type specific dissection */
     switch (control_frame_type)
@@ -1138,10 +1231,10 @@ void dissect_common_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
             offset = dissect_common_timing_adjustment(pinfo, tree, tvb, offset, p_fp_info);
             break;
         case COMMON_DL_SYNCHRONISATION:
-            offset = dissect_common_dl_syncronisation(pinfo, tree, tvb, offset, p_fp_info);
+            offset = dissect_common_dl_synchronisation(pinfo, tree, tvb, offset, p_fp_info);
             break;
         case COMMON_UL_SYNCHRONISATION:
-            offset = dissect_common_ul_syncronisation(pinfo, tree, tvb, offset, p_fp_info);
+            offset = dissect_common_ul_synchronisation(pinfo, tree, tvb, offset, p_fp_info);
             break;
         case COMMON_DL_NODE_SYNCHRONISATION:
             offset = dissect_common_dl_node_synchronisation(pinfo, tree, tvb, offset);
@@ -1177,23 +1270,20 @@ void dissect_common_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
 /**************************/
 /* Dissect a RACH channel */
-void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                               int offset, struct fp_info *p_fp_info)
+static void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                                      int offset, struct fp_info *p_fp_info)
 {
     gboolean is_control_frame;
 
     /* Header CRC */
-    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
 
     /* Frame Type */
     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
-    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
-    }
+    col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
 
     if (is_control_frame)
     {
@@ -1201,7 +1291,6 @@ void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     }
     else
     {
-        int num_tbs = 0;
         guint8 cfn;
         guint32 propagation_delay = 0;
         proto_item *propagation_delay_ti = NULL;
@@ -1214,16 +1303,13 @@ void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
         /* CFN */
         cfn = tvb_get_guint8(tvb, offset);
-        proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
-        if (check_col(pinfo->cinfo, COL_INFO))
-        {
-            col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
-        }
+        col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
 
         /* TFI */
-        proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
         if (p_fp_info->channel == CHANNEL_RACH_FDD)
@@ -1240,7 +1326,7 @@ void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
         {
             /* Rx Timing Deviation */
             rx_timing_deviation = tvb_get_guint8(tvb, offset);
-            rx_timing_deviation_ti = proto_tree_add_item(tree, hf_fp_rx_timing_deviation, tvb, offset, 1, FALSE);
+            rx_timing_deviation_ti = proto_tree_add_item(tree, hf_fp_rx_timing_deviation, tvb, offset, 1, ENC_BIG_ENDIAN);
             offset++;
         }
 
@@ -1249,23 +1335,24 @@ void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
             /* Received SYNC UL Timing Deviation */
             received_sync_ul_timing_deviation = tvb_get_guint8(tvb, offset);
             received_sync_ul_timing_deviation_ti =
-                 proto_tree_add_item(tree, hf_fp_received_sync_ul_timing_deviation, tvb, offset, 1, FALSE);
+                 proto_tree_add_item(tree, hf_fp_received_sync_ul_timing_deviation, tvb, offset, 1, ENC_BIG_ENDIAN);
             offset++;
         }
 
         /* TB data */
-        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
+        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_rach_handle);
 
         /* CRCIs */
-        offset = dissect_crci_bits(tvb, pinfo, tree, num_tbs, offset);
+        offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
 
         /* Info introduced in R6 */
-        if ((p_fp_info->release == 6) ||
-            (p_fp_info->release == 7))
+        /* only check if it looks as if they are present */
+        if (((p_fp_info->release == 6) || (p_fp_info->release == 7)) &&
+            tvb_length_remaining(tvb, offset) > 2)
         {
             int n;
             guint8 flags;
-            guint8 flag_bytes = 0;
+            /* guint8 flag_bytes = 0; */
 
             gboolean cell_portion_id_present = FALSE;
             gboolean ext_propagation_delay_present = FALSE;
@@ -1287,7 +1374,7 @@ void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
                 /* Read next byte */
                 flags = tvb_get_guint8(tvb, offset);
-                flag_bytes++;
+                /* flag_bytes++ */
 
                 /* Dissect individual bits */
                 for (n=0; n < 8; n++)
@@ -1300,19 +1387,19 @@ void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
                                     /* Ext propagation delay */
                                     ext_propagation_delay_present = TRUE;
                                     proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_ext_propagation_delay_present,
-                                                        tvb, offset, 1, FALSE);
+                                                        tvb, offset, 1, ENC_BIG_ENDIAN);
                                     break;
                                 case Division_TDD_128:
                                     /* Ext Rx Sync UL Timing */
                                     ext_rx_sync_ul_timing_deviation_present = TRUE;
                                     proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_ext_rx_sync_ul_timing_deviation_present,
-                                                        tvb, offset, 1, FALSE);
-        
+                                                        tvb, offset, 1, ENC_BIG_ENDIAN);
+
                                     break;
                                 default:
                                     /* Not defined */
-                                    proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_new_ie_flag_unused[n],
-                                                        tvb, offset, 1, FALSE);
+                                    proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_new_ie_flag_unused[6],
+                                                        tvb, offset, 1, ENC_BIG_ENDIAN);
                                     break;
                             }
                             break;
@@ -1323,28 +1410,29 @@ void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
                                     /* Cell Portion ID */
                                     cell_portion_id_present = TRUE;
                                     proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_cell_portion_id_present,
-                                                        tvb, offset, 1, FALSE);
+                                                        tvb, offset, 1, ENC_BIG_ENDIAN);
                                     break;
                                 case Division_TDD_128:
                                     /* AOA */
                                     angle_of_arrival_present = TRUE;
                                     proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_angle_of_arrival_present,
-                                                        tvb, offset, 1, FALSE);
+                                                        tvb, offset, 1, ENC_BIG_ENDIAN);
                                     break;
                                 case Division_TDD_384:
                                 case Division_TDD_768:
                                     /* Extended Rx Timing Deviation */
                                     ext_rx_timing_deviation_present = TRUE;
                                     proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_ext_rx_timing_deviation_present,
-                                                        tvb, offset, 1, FALSE);
+                                                        tvb, offset, 1, ENC_BIG_ENDIAN);
                                     break;
                             }
                             break;
 
                         default:
                             /* No defined meanings */
+                            /* Visual Studio Code Analyzer wrongly thinks n can be 7 here. It can't */
                             proto_tree_add_item(new_ie_flags_tree, hf_fp_rach_new_ie_flag_unused[n],
-                                                tvb, offset, 1, FALSE);
+                                                tvb, offset, 1, ENC_BIG_ENDIAN);
                             break;
                     }
                     if ((flags >> (7-n)) & 0x01)
@@ -1361,7 +1449,7 @@ void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
             /* Cell Portion ID */
             if (cell_portion_id_present) {
-                    proto_tree_add_item(tree, hf_fp_cell_portion_id, tvb, offset, 1, FALSE);
+                    proto_tree_add_item(tree, hf_fp_cell_portion_id, tvb, offset, 1, ENC_BIG_ENDIAN);
                     offset++;
             }
 
@@ -1378,7 +1466,7 @@ void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
                     case Division_TDD_768:
                         bits_to_extend = 2;
                         break;
-    
+
                     default:
                         /* TODO: report unexpected division type */
                         bits_to_extend = 1;
@@ -1391,7 +1479,7 @@ void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
                                        " (extended to 0x%x)",
                                        rx_timing_deviation);
                 proto_tree_add_bits_item(tree, hf_fp_extended_bits, tvb,
-                                         offset*8 + (8-bits_to_extend), bits_to_extend, FALSE);
+                                         offset*8 + (8-bits_to_extend), bits_to_extend, ENC_BIG_ENDIAN);
                 offset++;
             }
 
@@ -1399,7 +1487,7 @@ void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
             if (ext_propagation_delay_present)
             {
                 guint16 extra_bits = tvb_get_ntohs(tvb, offset) & 0x03ff;
-                proto_tree_add_item(tree, hf_fp_ext_propagation_delay, tvb, offset, 2, FALSE);
+                proto_tree_add_item(tree, hf_fp_ext_propagation_delay, tvb, offset, 2, ENC_BIG_ENDIAN);
 
                 /* Adding 10 bits to original 8 */
                 proto_item_append_text(propagation_delay_ti, " (extended to %u)",
@@ -1410,7 +1498,7 @@ void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
             /* Angle of Arrival (AOA) */
             if (angle_of_arrival_present)
             {
-                proto_tree_add_item(tree, hf_fp_angle_of_arrival, tvb, offset, 2, FALSE);
+                proto_tree_add_item(tree, hf_fp_angle_of_arrival, tvb, offset, 2, ENC_BIG_ENDIAN);
                 offset += 2;
             }
 
@@ -1420,7 +1508,7 @@ void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
                 /* Ext received Sync UL Timing Deviation */
                 extra_bits = tvb_get_ntohs(tvb, offset) & 0x1fff;
-                proto_tree_add_item(tree, hf_fp_ext_received_sync_ul_timing_deviation, tvb, offset, 2, FALSE);
+                proto_tree_add_item(tree, hf_fp_ext_received_sync_ul_timing_deviation, tvb, offset, 2, ENC_BIG_ENDIAN);
 
                 /* Adding 13 bits to original 8 */
                 proto_item_append_text(received_sync_ul_timing_deviation_ti, " (extended to %u)",
@@ -1437,23 +1525,20 @@ void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
 /**************************/
 /* Dissect a FACH channel */
-void dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                               int offset, struct fp_info *p_fp_info)
+static void dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                                      int offset, struct fp_info *p_fp_info)
 {
     gboolean is_control_frame;
 
     /* Header CRC */
-    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
 
     /* Frame Type */
     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
-    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
-    }
+    col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
 
     if (is_control_frame)
     {
@@ -1461,23 +1546,19 @@ void dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     }
     else
     {
-        int num_tbs = 0;
         guint8 cfn;
 
         /* DATA */
 
         /* CFN */
         cfn = tvb_get_guint8(tvb, offset);
-        proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
-        if (check_col(pinfo->cinfo, COL_INFO))
-        {
-            col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
-        }
+        col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
 
         /* TFI */
-        proto_tree_add_item(tree, hf_fp_fach_tfi, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_fach_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
         /* Transmit power level */
@@ -1486,7 +1567,7 @@ void dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
         offset++;
 
         /* TB data */
-        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
+        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_fach_handle);
 
         /* New IE flags (if it looks as though they are present) */
         if ((p_fp_info->release == 7) &&
@@ -1498,7 +1579,7 @@ void dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
             if (aoa_present)
             {
-                proto_tree_add_item(tree, hf_fp_angle_of_arrival, tvb, offset, 2, FALSE);
+                proto_tree_add_item(tree, hf_fp_angle_of_arrival, tvb, offset, 2, ENC_BIG_ENDIAN);
                 offset += 2;
             }
         }
@@ -1511,23 +1592,20 @@ void dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
 /**************************/
 /* Dissect a DSCH channel */
-void dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                               int offset, struct fp_info *p_fp_info)
+static void dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                                      int offset, struct fp_info *p_fp_info)
 {
     gboolean is_control_frame;
 
     /* Header CRC */
-    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
 
     /* Frame Type */
     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
-    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
-    }
+    col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
 
     if (is_control_frame)
     {
@@ -1535,23 +1613,19 @@ void dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     }
     else
     {
-        int num_tbs = 0;
         guint8 cfn;
 
         /* DATA */
 
         /* CFN */
         cfn = tvb_get_guint8(tvb, offset);
-        proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
-        if (check_col(pinfo->cinfo, COL_INFO))
-        {
-            col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
-        }
+        col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
 
         /* TFI */
-        proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
 
@@ -1566,14 +1640,14 @@ void dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
             offset++;
 
             /* Code number */
-            proto_tree_add_item(tree, hf_fp_code_number, tvb, offset, 1, FALSE);
+            proto_tree_add_item(tree, hf_fp_code_number, tvb, offset, 1, ENC_BIG_ENDIAN);
             offset++;
 
             /* Spreading Factor (3 bits) */
-            proto_tree_add_item(tree, hf_fp_spreading_factor, tvb, offset, 1, FALSE);
+            proto_tree_add_item(tree, hf_fp_spreading_factor, tvb, offset, 1, ENC_BIG_ENDIAN);
 
             /* MC info (4 bits)*/
-            proto_tree_add_item(tree, hf_fp_mc_info, tvb, offset, 1, FALSE);
+            proto_tree_add_item(tree, hf_fp_mc_info, tvb, offset, 1, ENC_BIG_ENDIAN);
 
             /* Last bit of this byte is spare */
             offset++;
@@ -1583,7 +1657,7 @@ void dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
             /* Normal case */
 
             /* PDSCH Set Id */
-            proto_tree_add_item(tree, hf_fp_pdsch_set_id, tvb, offset, 1, FALSE);
+            proto_tree_add_item(tree, hf_fp_pdsch_set_id, tvb, offset, 1, ENC_BIG_ENDIAN);
             offset++;
 
             /* Transmit power level */
@@ -1593,7 +1667,7 @@ 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);
+        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, NULL);
 
         /* Spare Extension and Payload CRC */
         dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
@@ -1603,23 +1677,20 @@ void dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
 /**************************/
 /* Dissect a USCH channel */
-void dissect_usch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                               int offset, struct fp_info *p_fp_info)
+static void dissect_usch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                                      int offset, struct fp_info *p_fp_info)
 {
     gboolean is_control_frame;
 
     /* Header CRC */
-    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
 
     /* Frame Type */
     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
-    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
-    }
+    col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
 
     if (is_control_frame)
     {
@@ -1627,7 +1698,6 @@ void dissect_usch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     }
     else
     {
-        int num_tbs = 0;
         guint cfn;
         guint16 rx_timing_deviation;
         proto_item *rx_timing_deviation_ti;
@@ -1636,33 +1706,30 @@ void dissect_usch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
         /* CFN */
         cfn = tvb_get_guint8(tvb, offset);
-        proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
-        if (check_col(pinfo->cinfo, COL_INFO))
-        {
-            col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
-        }
+        col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
 
         /* TFI */
-        proto_tree_add_item(tree, hf_fp_usch_tfi, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_usch_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
         /* Rx Timing Deviation */
         rx_timing_deviation = tvb_get_guint8(tvb, offset);
         rx_timing_deviation_ti = proto_tree_add_item(tree, hf_fp_rx_timing_deviation,
-                                                     tvb, offset, 1, FALSE);
+                                                     tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
         /* TB data */
-        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
+        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, NULL);
 
         /* QE */
-        proto_tree_add_item(tree, hf_fp_quality_estimate, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_quality_estimate, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
         /* CRCIs */
-        offset = dissect_crci_bits(tvb, pinfo, tree, num_tbs, offset);
+        offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
 
         /* New IEs */
         if ((p_fp_info->release == 7) &&
@@ -1691,25 +1758,22 @@ void dissect_usch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
 /**************************/
 /* Dissect a PCH channel  */
-void dissect_pch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                              int offset, struct fp_info *p_fp_info)
+static void dissect_pch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                                     int offset, struct fp_info *p_fp_info)
 {
     gboolean is_control_frame;
     guint16  pch_cfn;
     gboolean paging_indication;
 
     /* Header CRC */
-    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
 
     /* Frame Type */
     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
-    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
-    }
+    col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
 
     if (is_control_frame)
     {
@@ -1717,27 +1781,22 @@ void dissect_pch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
     }
     else
     {
-        int num_tbs = 0;
-
         /* DATA */
 
         /* 12-bit CFN value */
-        proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, FALSE);
+        proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, ENC_BIG_ENDIAN);
         pch_cfn = (tvb_get_ntohs(tvb, offset) & 0xfff0) >> 4;
         offset++;
 
-        if (check_col(pinfo->cinfo, COL_INFO))
-        {
-            col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%04u ", pch_cfn);
-        }
+        col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%04u ", pch_cfn);
 
         /* Paging indication */
-        proto_tree_add_item(tree, hf_fp_pch_pi, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_pch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
         paging_indication = tvb_get_guint8(tvb, offset) & 0x01;
         offset++;
 
         /* 5-bit TFI */
-        proto_tree_add_item(tree, hf_fp_pch_tfi, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_pch_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
         /* Optional paging indications */
@@ -1747,13 +1806,13 @@ void dissect_pch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
             ti = proto_tree_add_item(tree, hf_fp_paging_indication_bitmap, tvb,
                                      offset,
                                      (p_fp_info->paging_indications+7) / 8,
-                                     FALSE);
+                                     ENC_NA);
             proto_item_append_text(ti, " (%u bits)", p_fp_info->paging_indications);
             offset += ((p_fp_info->paging_indications+7) / 8);
         }
 
         /* TB data */
-        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
+        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_pch_handle);
 
         /* Spare Extension and Payload CRC */
         dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
@@ -1763,23 +1822,20 @@ void dissect_pch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
 
 /**************************/
 /* Dissect a CPCH channel */
-void dissect_cpch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                               int offset, struct fp_info *p_fp_info)
+static void dissect_cpch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                                      int offset, struct fp_info *p_fp_info)
 {
     gboolean is_control_frame;
 
     /* Header CRC */
-    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
 
     /* Frame Type */
     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
-    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
-    }
+    col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
 
     if (is_control_frame)
     {
@@ -1787,23 +1843,19 @@ void dissect_cpch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     }
     else
     {
-        int num_tbs = 0;
         guint cfn;
 
         /* DATA */
 
         /* CFN */
         cfn = tvb_get_guint8(tvb, offset);
-        proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
-        if (check_col(pinfo->cinfo, COL_INFO))
-        {
-            col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
-        }
+        col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
 
         /* TFI */
-        proto_tree_add_item(tree, hf_fp_cpch_tfi, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_cpch_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
         /* Propagation delay */
@@ -1812,10 +1864,10 @@ void dissect_cpch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
         offset++;
 
         /* TB data */
-        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
+        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, NULL);
 
         /* CRCIs */
-        offset = dissect_crci_bits(tvb, pinfo, tree, num_tbs, offset);
+        offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
 
         /* Spare Extension and Payload CRC */
         dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
@@ -1825,23 +1877,20 @@ void dissect_cpch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
 /**************************/
 /* Dissect a BCH channel  */
-void dissect_bch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                              int offset, struct fp_info *p_fp_info)
+static void dissect_bch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                                     int offset, struct fp_info *p_fp_info)
 {
     gboolean is_control_frame;
 
     /* Header CRC */
-    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
 
     /* Frame Type */
     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
-    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
-    }
+    col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
 
     if (is_control_frame)
     {
@@ -1852,23 +1901,20 @@ void dissect_bch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
 
 /********************************/
 /* Dissect an IUR DSCH channel  */
-void dissect_iur_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                                   int offset, struct fp_info *p_fp_info _U_)
+static void dissect_iur_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                                          int offset, struct fp_info *p_fp_info)
 {
     gboolean is_control_frame;
 
     /* Header CRC */
-    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
 
     /* Frame Type */
     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
-    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
-    }
+    col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
 
     if (is_control_frame)
     {
@@ -1886,45 +1932,48 @@ void dissect_iur_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree
 /************************/
 /* DCH control messages */
 
-int dissect_dch_timing_adjustment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
+static int dissect_dch_timing_adjustment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
 {
     guint8 control_cfn;
     gint16 toa;
+    proto_item *toa_ti;
 
     /* CFN control */
     control_cfn = tvb_get_guint8(tvb, offset);
-    proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
     /* ToA */
     toa = tvb_get_ntohs(tvb, offset);
-    proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, FALSE);
+    toa_ti = proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, ENC_BIG_ENDIAN);
     offset += 2;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_fstr(pinfo->cinfo, COL_INFO,
-                        " CFN = %u, ToA = %d", control_cfn, toa);
-    }
+    expert_add_info_format(pinfo, toa_ti,
+                           PI_SEQUENCE, PI_WARN,
+                           "Timing adjustmentment reported (%f ms)",
+                           (float)(toa / 8));
+
+    col_append_fstr(pinfo->cinfo, COL_INFO,
+                    " CFN = %u, ToA = %d", control_cfn, toa);
 
     return offset;
 }
 
-int dissect_dch_rx_timing_deviation(packet_info *pinfo, proto_tree *tree,
-                                    tvbuff_t *tvb, int offset,
-                                    struct fp_info *p_fp_info)
+static int dissect_dch_rx_timing_deviation(packet_info *pinfo, proto_tree *tree,
+                                           tvbuff_t *tvb, int offset,
+                                           struct fp_info *p_fp_info)
 {
     guint16 timing_deviation = 0;
     gint timing_deviation_chips = 0;
     proto_item *timing_deviation_ti = NULL;
 
     /* CFN control */
-    proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
     /* Rx Timing Deviation */
     timing_deviation = tvb_get_guint8(tvb, offset);
-    timing_deviation_ti = proto_tree_add_item(tree, hf_fp_dch_rx_timing_deviation, tvb, offset, 1, FALSE);
+    timing_deviation_ti = proto_tree_add_item(tree, hf_fp_dch_rx_timing_deviation, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
     /* May be extended in R7, but in this case there are at least 2 bytes remaining */
@@ -1937,9 +1986,9 @@ int dissect_dch_rx_timing_deviation(packet_info *pinfo, proto_tree *tree,
 
         /* Read flags */
         proto_tree_add_bits_ret_val(tree, hf_fp_e_rucch_present, tvb,
-                                    offset*8 + 6, 1, &e_rucch_present, FALSE);
+                                    offset*8 + 6, 1, &e_rucch_present, ENC_BIG_ENDIAN);
         proto_tree_add_bits_ret_val(tree, hf_fp_extended_bits_present, tvb,
-                                    offset*8 + 7, 1, &extended_bits_present, FALSE);
+                                    offset*8 + 7, 1, &extended_bits_present, ENC_BIG_ENDIAN);
         offset++;
 
         /* Optional E-RUCCH */
@@ -1966,12 +2015,11 @@ int dissect_dch_rx_timing_deviation(packet_info *pinfo, proto_tree *tree,
                                                "Error: expecting TDD-384 or TDD-768");
                         bit_offset = 6;
                     }
-                    
             }
 
-            proto_tree_add_item(tree, hf_fp_dch_e_rucch_flag, tvb, offset, 1, FALSE);
+            proto_tree_add_item(tree, hf_fp_dch_e_rucch_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
             proto_tree_add_bits_item(tree, hf_fp_dch_e_rucch_flag, tvb,
-                                     offset*8 + bit_offset, 1, FALSE);
+                                     offset*8 + bit_offset, 1, ENC_BIG_ENDIAN);
         }
 
         /* Timing deviation may be extended by another:
@@ -2003,7 +2051,7 @@ int dissect_dch_rx_timing_deviation(packet_info *pinfo, proto_tree *tree,
                                    " (extended to 0x%x)",
                                    timing_deviation);
             proto_tree_add_bits_item(tree, hf_fp_extended_bits, tvb,
-                                     offset*8 + (8-bits_to_extend), bits_to_extend, FALSE);
+                                     offset*8 + (8-bits_to_extend), bits_to_extend, ENC_BIG_ENDIAN);
             offset++;
         }
     }
@@ -2012,106 +2060,93 @@ int dissect_dch_rx_timing_deviation(packet_info *pinfo, proto_tree *tree,
     proto_item_append_text(timing_deviation_ti, " (%d chips)",
                            timing_deviation_chips);
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_fstr(pinfo->cinfo, COL_INFO, " deviation = %u (%d chips)",
-                        timing_deviation, timing_deviation_chips);
-    }
+    col_append_fstr(pinfo->cinfo, COL_INFO, " deviation = %u (%d chips)",
+                    timing_deviation, timing_deviation_chips);
 
     return offset;
 }
 
-int dissect_dch_dl_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
+static 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);
-    proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u", cfn);
-    }
+    col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u", cfn);
 
     return offset;
 }
 
-int dissect_dch_ul_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
+static int dissect_dch_ul_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
 {
     guint8 cfn;
     gint16 toa;
 
     /* CFN control */
     cfn = tvb_get_guint8(tvb, offset);
-    proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
     /* ToA */
     toa = tvb_get_ntohs(tvb, offset);
-    proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, FALSE);
+    proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, ENC_BIG_ENDIAN);
     offset += 2;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, ToA = %d",
-                        cfn, toa);
-    }
+    col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, ToA = %d",
+                    cfn, toa);
 
     return offset;
 }
 
-int dissect_dch_outer_loop_power_control(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)
 {
     /* UL 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, " UL SIR Target = %f", target);
-    }
+    col_append_fstr(pinfo->cinfo, COL_INFO, " UL SIR Target = %f", target);
 
     return offset;
 }
 
-int dissect_dch_dl_node_synchronisation(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)
 {
     return dissect_common_dl_node_synchronisation(pinfo, tree, tvb, offset);
 }
 
-int dissect_dch_ul_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)
 {
     return dissect_common_ul_node_synchronisation(pinfo, tree, tvb, offset);
 }
 
-int dissect_dch_radio_interface_parameter_update(proto_tree *tree, packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
+static int dissect_dch_radio_interface_parameter_update(proto_tree *tree, packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
 {
     int n;
-    guint8 cfn;
     guint8 value;
 
     /* Show defined flags in these 2 bytes */
     for (n=4; n >= 0; n--)
     {
-        proto_tree_add_item(tree, hf_fp_radio_interface_parameter_update_flag[n], tvb, offset, 2, FALSE);
+        proto_tree_add_item(tree, hf_fp_radio_interface_parameter_update_flag[n], tvb, offset, 2, ENC_BIG_ENDIAN);
     }
     offset += 2;
 
     /* CFN  */
-    cfn = tvb_get_guint8(tvb, offset);
-    proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
+    tvb_get_guint8(tvb, offset);
+    proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
     /* DPC mode */
-    proto_tree_add_item(tree, hf_fp_dpc_mode, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_dpc_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
 
     /* TPC PO */
-    proto_tree_add_item(tree, hf_fp_tpc_po, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_tpc_po, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
     /* Multiple RL sets indicator */
-    proto_tree_add_item(tree, hf_fp_multiple_rl_set_indicator, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_multiple_rl_set_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset += 2;
 
     /* MAX_UE_TX_POW */
@@ -2122,8 +2157,8 @@ int dissect_dch_radio_interface_parameter_update(proto_tree *tree, packet_info *
     return offset;
 }
 
-int dissect_dch_timing_advance(proto_tree *tree, packet_info *pinfo,
-                               tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
+static int dissect_dch_timing_advance(proto_tree *tree, packet_info *pinfo,
+                                      tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
 {
     guint8 cfn;
     guint16 timing_advance;
@@ -2131,7 +2166,7 @@ int dissect_dch_timing_advance(proto_tree *tree, packet_info *pinfo,
 
     /* CFN control */
     cfn = tvb_get_guint8(tvb, offset);
-    proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
     /* Timing Advance */
@@ -2157,29 +2192,23 @@ int dissect_dch_timing_advance(proto_tree *tree, packet_info *pinfo,
     }
 
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, TA = %u",
-                        cfn, timing_advance);
-    }
+    col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, TA = %u",
+                    cfn, timing_advance);
 
     return offset;
 }
 
-int dissect_dch_tnl_congestion_indication(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)
 {
     guint64 status;
 
     /* Congestion status */
     proto_tree_add_bits_ret_val(tree, hf_fp_congestion_status, tvb,
-                                offset*8 + 6, 2, &status, FALSE);
+                                offset*8 + 6, 2, &status, ENC_BIG_ENDIAN);
     offset++;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_fstr(pinfo->cinfo, COL_INFO, " status = %s",
-                        val_to_str((guint16)status, congestion_status_vals, "unknown"));
-    }
+    col_append_fstr(pinfo->cinfo, COL_INFO, " status = %s",
+                    val_to_str_const((guint16)status, congestion_status_vals, "unknown"));
 
     return offset;
 }
@@ -2188,20 +2217,17 @@ int dissect_dch_tnl_congestion_indication(proto_tree *tree, packet_info *pinfo,
 
 
 /* DCH control frame */
-void dissect_dch_control_frame(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset,
-                               struct fp_info *p_fp_info)
+static void dissect_dch_control_frame(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset,
+                                      struct fp_info *p_fp_info)
 {
     /* Control frame type */
     guint8 control_frame_type = tvb_get_guint8(tvb, offset);
-    proto_tree_add_item(tree, hf_fp_dch_control_frame_type, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_dch_control_frame_type, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_str(pinfo->cinfo, COL_INFO,
-                       val_to_str(control_frame_type,
-                                  dch_control_frame_type_vals, "Unknown"));
-    }
+    col_append_str(pinfo->cinfo, COL_INFO,
+                   val_to_str_const(control_frame_type,
+                                    dch_control_frame_type_vals, "Unknown"));
 
     switch (control_frame_type)
     {
@@ -2243,27 +2269,24 @@ void dissect_dch_control_frame(proto_tree *tree, packet_info *pinfo, tvbuff_t *t
 
 /*******************************/
 /* Dissect a DCH channel       */
-void dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                              int offset, struct fp_info *p_fp_info)
+static void dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                                     int offset, struct fp_info *p_fp_info)
 {
     gboolean is_control_frame;
     guint8   cfn;
 
     /* Header CRC */
-    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
 
     /* Frame Type */
     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
-    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_str(pinfo->cinfo, COL_INFO,
-                       is_control_frame ? " [Control] " :
-                                          ((p_fp_info->is_uplink) ? " [ULData] " :
-                                                                    " [DLData] " ));
-    }
+    col_append_str(pinfo->cinfo, COL_INFO,
+                   is_control_frame ? " [Control] " :
+                                      ((p_fp_info->is_uplink) ? " [ULData] " :
+                                                                " [DLData] " ));
 
     if (is_control_frame)
     {
@@ -2275,39 +2298,35 @@ void dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
         /************************/
         /* DCH data here        */
         int chan;
-        int num_tbs = 0;
 
         /* CFN */
-        proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
         cfn = tvb_get_guint8(tvb, offset);
         offset++;
 
-        if (check_col(pinfo->cinfo, COL_INFO))
-        {
-            col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
-        }
+        col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
 
         /* One TFI for each channel */
         for (chan=0; chan < p_fp_info->num_chans; chan++)
         {
-            proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, FALSE);
+            proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, ENC_BIG_ENDIAN);
             offset++;
         }
 
         /* Dissect TB data */
-        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
+        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_dch_handle);
 
         /* QE (uplink only) */
         if (p_fp_info->is_uplink)
         {
-            proto_tree_add_item(tree, hf_fp_quality_estimate, tvb, offset, 1, FALSE);
+            proto_tree_add_item(tree, hf_fp_quality_estimate, tvb, offset, 1, ENC_BIG_ENDIAN);
             offset++;
         }
 
         /* CRCI bits (uplink only) */
         if (p_fp_info->is_uplink)
         {
-            offset = dissect_crci_bits(tvb, pinfo, tree, num_tbs, offset);
+            offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
         }
 
         /* Spare extension and payload CRC (optional) */
@@ -2320,27 +2339,29 @@ void dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
 
 /**********************************/
 /* Dissect an E-DCH channel       */
-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_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                                       int offset, struct fp_info *p_fp_info,
+                                       gboolean is_common)
 {
     gboolean is_control_frame;
     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);
+    proto_tree_add_item(tree, hf_fp_edch_header_crc, tvb, offset, 2, ENC_BIG_ENDIAN);
 
     /* Frame Type */
     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
-    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
-    }
+    col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
 
     if (is_control_frame)
     {
@@ -2355,9 +2376,10 @@ void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
         guint  bit_offset = 0;
         guint  total_pdus = 0;
         guint  total_bits = 0;
+        gboolean dissected = FALSE;
 
         /* FSN */
-        proto_tree_add_item(tree, hf_fp_edch_fsn, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_edch_fsn, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
         /* Number of subframes.
@@ -2381,9 +2403,16 @@ void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
 
         /* CFN */
         cfn = tvb_get_guint8(tvb, offset);
-        proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
+        /* Remainder of T2 or common data frames differ here... */
+        if (p_fp_info->edch_type == 1) {
+            dissect_e_dch_t2_or_common_channel_info(tvb, pinfo, tree, offset, p_fp_info,
+                                                    number_of_subframes, is_common);
+            return;
+        }
+
         /* EDCH subframe header list */
         for (n=0; n < number_of_subframes; n++)
         {
@@ -2399,18 +2428,18 @@ void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
 
             /* Number of HARQ Retransmissions */
             proto_tree_add_item(subframe_header_tree, hf_fp_edch_harq_retransmissions, tvb,
-                                offset, 1, FALSE);
+                                offset, 1, ENC_BIG_ENDIAN);
 
             /* 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);
+            proto_tree_add_bits_item(subframe_header_tree, hf_fp_edch_subframe_number, tvb,
+                                     offset*8+5, 1, ENC_BIG_ENDIAN);
             offset++;
 
             /* Number of MAC-es PDUs */
             subframes[n].number_of_mac_es_pdus = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
             proto_tree_add_item(subframe_header_tree, hf_fp_edch_number_of_mac_es_pdus,
-                                tvb, offset, 1, FALSE);
+                                tvb, offset, 1, ENC_BIG_ENDIAN);
             bit_offset = 4;
 
             proto_item_append_text(subframe_header_ti, " %u header (%u MAC-es PDUs)",
@@ -2421,24 +2450,42 @@ void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
             for (i=0; i < subframes[n].number_of_mac_es_pdus; i++)
             {
                 guint64 ddi;
-                int     ddi_offset;
                 guint64 n_pdus;
-                int     n_pdus_offset;
+                proto_item *ddi_ti;
+                gint ddi_size = -1;
+                int     p;
 
                 /* DDI (6 bits) */
-                ddi_offset = offset + (bit_offset / 8);
+                ddi_ti = proto_tree_add_bits_ret_val(subframe_header_tree, hf_fp_edch_ddi, tvb,
+                                                     offset*8 + bit_offset, 6, &ddi, ENC_BIG_ENDIAN);
 
-                proto_tree_add_bits_ret_val(subframe_header_tree, hf_fp_edch_ddi, tvb,
-                                            offset*8 + bit_offset, 6, &ddi, FALSE);
+                /* Look up the size from this DDI value */
+                for (p=0; p < p_fp_info->no_ddi_entries; p++)
+                {
+                    if (ddi == p_fp_info->edch_ddi[p])
+                    {
+                        ddi_size = p_fp_info->edch_macd_pdu_size[p];
+                        break;
+                    }
+                }
+                if (ddi_size == -1)
+                {
+                    expert_add_info_format(pinfo, ddi_ti,
+                                           PI_MALFORMED, PI_ERROR,
+                                           "DDI %u not defined for this UE!", (guint)ddi);
+                    return;
+                }
+                else
+                {
+                    proto_item_append_text(ddi_ti, " (%d bits)", ddi_size);
+                }
 
                 subframes[n].ddi[i] = (guint8)ddi;
                 bit_offset += 6;
 
                 /* Number of MAC-d PDUs (6 bits) */
-                n_pdus_offset = offset + (bit_offset / 8);
-
                 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);
+                                            offset*8 + bit_offset, 6, &n_pdus, ENC_BIG_ENDIAN);
 
                 subframes[n].number_of_mac_d_pdus[i] = (guint8)n_pdus;
                 bit_offset += 6;
@@ -2471,9 +2518,11 @@ void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
             {
                 int         m;
                 guint16     size = 0;
-                guint8      tsn;
+                /* guint8      tsn; */
                 guint       send_size;
                 proto_item  *ti;
+                int         macd_idx;
+                proto_tree  *maces_tree = NULL;
 
                 /* Look up mac-d pdu size for this ddi */
                 for (m=0; m < p_fp_info->no_ddi_entries; m++)
@@ -2497,14 +2546,14 @@ void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
                 /* 2 bits spare */
                 proto_tree_add_item(subframe_tree, hf_fp_edch_pdu_padding, tvb,
                                     offset + (bit_offset/8),
-                                    1, FALSE);
+                                    1, ENC_BIG_ENDIAN);
                 bit_offset += 2;
 
                 /* TSN */
-                tsn = (tvb_get_guint8(tvb, offset + (bit_offset/8)) & 0x3f);
+                /* tsn = (tvb_get_guint8(tvb, offset + (bit_offset/8)) & 0x3f); */
                 proto_tree_add_item(subframe_tree, hf_fp_edch_tsn, tvb,
                                     offset + (bit_offset/8),
-                                    1, FALSE);
+                                    1, ENC_BIG_ENDIAN);
                 bit_offset += 6;
 
                 /* PDU */
@@ -2513,16 +2562,37 @@ void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
                     ti = proto_tree_add_item(subframe_tree, hf_fp_edch_mac_es_pdu, tvb,
                                              offset + (bit_offset/8),
                                              ((bit_offset % 8) + send_size + 7) / 8,
-                                             FALSE);
-                    proto_item_append_text(ti, " (%u * %u = %u bits, subframe %d)",
+                                             ENC_NA);
+                    proto_item_append_text(ti, " (%u * %u = %u bits, PDU %d)",
                                            size, subframes[n].number_of_mac_d_pdus[i],
                                            send_size, n);
+                    maces_tree = proto_item_add_subtree(ti, ett_fp_edch_maces);
+                }
+                for (macd_idx = 0; macd_idx < subframes[n].number_of_mac_d_pdus[i]; macd_idx++) {
+
+                    if (preferences_call_mac_dissectors) {
+                        tvbuff_t *next_tvb;
+                        pinfo->fd->subnum = macd_idx; /* set subframe number to current TB */
+                        /* create new TVB and pass further on */
+                        next_tvb = tvb_new_subset(tvb, offset + bit_offset/8,
+                                ((bit_offset % 8) + size + 7) / 8, -1);
+                        /* TODO: use maces_tree? */
+                        call_dissector(mac_fdd_edch_handle, next_tvb, pinfo, top_level_tree);
+                        dissected = TRUE;
+                    }
+                    else {
+                        /* Just add as a MAC-d PDU */
+                        proto_tree_add_item(maces_tree, hf_fp_mac_d_pdu, tvb,
+                                            offset + (bit_offset/8),
+                                            ((bit_offset % 8) + size + 7) / 8,
+                                            ENC_NA);
+                    }
+                    bit_offset += size;
                 }
+
                 bits_in_subframe += send_size;
                 mac_d_pdus_in_subframe += subframes[n].number_of_mac_d_pdus[i];
 
-                bit_offset += send_size;
-
                 /* Pad out to next byte */
                 if (bit_offset % 8)
                 {
@@ -2534,7 +2604,6 @@ void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
             {
                 /* Tree should cover entire subframe */
                 proto_item_set_len(subframe_ti, bit_offset/8);
-
                 /* Append summary info to subframe label */
                 proto_item_append_text(subframe_ti, " (%u bits in %u MAC-d PDUs)",
                                        bits_in_subframe, mac_d_pdus_in_subframe);
@@ -2545,8 +2614,9 @@ void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
             offset += (bit_offset/8);
         }
 
-        /* Report number of subframes in info column */
-        if (check_col(pinfo->cinfo, COL_INFO))
+        /* Report number of subframes in info column
+         * do this only if no other dissector was called */
+        if (dissected == FALSE)
         {
             col_append_fstr(pinfo->cinfo, COL_INFO,
                             " CFN = %03u   (%u bits in %u pdus in %u subframes)",
@@ -2559,28 +2629,249 @@ void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
     }
 }
 
+/* Dissect the remainder of the T2 or common frame that differs from T1 */
+static void dissect_e_dch_t2_or_common_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                                                    int offset, struct fp_info *p_fp_info,
+                                                    int number_of_subframes,
+                                                    gboolean is_common)
+{
+    int n;
+    int pdu_no;
+    static struct edch_t2_subframe_info subframes[16];
+    guint64 total_macis_sdus;
+    guint16 macis_sdus_found = 0;
+    guint16 macis_pdus = 0;
+    guint32 total_bytes = 0;
+    gboolean F = TRUE;  /* We want to continue loop if get E-RNTI indication... */
+    proto_item *subframe_macis_descriptors_ti = NULL;
+    gint bit_offset;
+
+    /* User Buffer size */
+    proto_tree_add_bits_item(tree, hf_fp_edch_user_buffer_size, tvb, offset*8,
+                             18, ENC_BIG_ENDIAN);
+    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, ENC_BIG_ENDIAN);
+    offset += 2;
+
+    if (is_common) {
+        /* E-RNTI */
+        proto_tree_add_item(tree, hf_fp_edch_e_rnti, tvb, offset, 2, ENC_BIG_ENDIAN);
+        offset += 2;
+    }
+
+    bit_offset = offset*8;
+    /* EDCH subframe header list */
+    for (n=0; n < number_of_subframes; n++) {
+        guint64    subframe_number;
+        guint64    no_of_macis_pdus;
+        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);
+
+        /* Spare bit */
+        bit_offset++;
+
+        if (!is_common) {
+            /* Number of HARQ Retransmissions */
+            proto_tree_add_item(subframe_header_tree, hf_fp_edch_harq_retransmissions, tvb,
+                                bit_offset/8, 1, ENC_BIG_ENDIAN);
+            bit_offset += 4;
+        }
+
+        /* Subframe number */
+        proto_tree_add_bits_ret_val(subframe_header_tree, hf_fp_edch_subframe_number, tvb,
+                                    bit_offset, 3, &subframe_number, ENC_BIG_ENDIAN);
+        subframes[n].subframe_number = (guint8)subframe_number;
+        bit_offset += 3;
+
+        /* Number of MAC-is PDUs */
+        proto_tree_add_bits_ret_val(subframe_header_tree, hf_fp_edch_number_of_mac_is_pdus, tvb,
+                                    bit_offset, 4, &no_of_macis_pdus, ENC_BIG_ENDIAN);
+        bit_offset += 4;
+        subframes[n].number_of_mac_is_pdus = (guint8)no_of_macis_pdus;
+        macis_pdus += subframes[n].number_of_mac_is_pdus;
+
+        /* Next 4 bits are spare for T2*/
+        if (!is_common) {
+            bit_offset += 4;
+        }
+
+        /* 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, is_common ? 1 : 2);
+    }
+    offset = bit_offset / 8;
+
+
+    /* 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, ENC_BIG_ENDIAN);
+                if (subframes[n].mac_is_lchid[pdu_no][subframes[n].number_of_mac_is_sdus[pdu_no]] == 15) {
+                    proto_item *ti;
+
+                    /* 4 bits of spare */
+                    offset++;
+
+                    /* E-RNTI */
+                    ti = proto_tree_add_item(tree, hf_fp_edch_e_rnti, tvb, offset, 2, ENC_BIG_ENDIAN);
+                    offset += 2;
+
+                    /* This is only allowed if:
+                       - its the common case AND
+                       - its the first descriptor */
+                    if (!is_common) {
+                        expert_add_info_format(pinfo, ti,
+                                               PI_MALFORMED, PI_ERROR,
+                                               "E-RNTI not supposed to appear for T2 EDCH frames");
+                    }
+                    if (subframes[n].number_of_mac_is_sdus[pdu_no] > 0) {
+                        expert_add_info_format(pinfo, ti,
+                                               PI_MALFORMED, PI_ERROR,
+                                               "E-RNTI must be first entry among descriptors");
+                    }
+                    continue;
+                }
+
+                /* 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, ENC_BIG_ENDIAN);
+                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, ENC_BIG_ENDIAN);
+
+                subframes[n].number_of_mac_is_sdus[pdu_no]++;
+
+                offset++;
+            } while (F == 0);
+        }
+    }
+
+    /* 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 subframe_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 PDU %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, ENC_BIG_ENDIAN);
+
+            /* TSN */
+            tsn = tvb_get_guint8(tvb, offset) & 0x03;
+            proto_tree_add_item(macis_pdu_tree, hf_fp_edch_macis_tsn, tvb, offset, 1, ENC_BIG_ENDIAN);
+
+            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],
+                                         ENC_NA);
+                proto_item_append_text(ti, " (%s Len=%u): %s",
+                                       val_to_str_const(subframes[n].mac_is_lchid[pdu_no][sdu_no], lchid_vals, "Unknown"),
+                                       subframes[n].mac_is_length[pdu_no][sdu_no],
+                                       tvb_bytes_to_str(tvb, offset, subframes[n].mac_is_length[pdu_no][sdu_no]));
+
+                offset += subframes[n].mac_is_length[pdu_no][sdu_no];
+                subframe_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, subframe_bytes, subframes[n].number_of_mac_is_sdus[pdu_no]);
+
+            proto_item_set_len(macis_pdu_ti, 1+subframe_bytes);
+            total_bytes += subframe_bytes;
+        }
+    }
+
+    /* Add data summary to info column */
+    col_append_fstr(pinfo->cinfo, COL_INFO, " (%u bytes in %u SDUs in %u MAC-is PDUs in %u subframes)",
+                    total_bytes, macis_sdus_found, macis_pdus, number_of_subframes);;
+
+    /* 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                              */
 /* The data format corresponds to the format              */
 /* described in R5 and R6, and frame type 1 in Release 7. */
-void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                                 int offset, struct fp_info *p_fp_info)
+static void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                                        int offset, struct fp_info *p_fp_info)
 {
     gboolean is_control_frame;
 
     /* Header CRC */
-    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
 
     /* Frame Type */
     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
-    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
-    }
+    col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
 
     if (is_control_frame)
     {
@@ -2600,52 +2891,47 @@ void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
             (p_fp_info->release == 7))
         {
             guint8 frame_seq_no = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
-            proto_tree_add_item(tree, hf_fp_frame_seq_nr, tvb, offset, 1, FALSE);
+            proto_tree_add_item(tree, hf_fp_frame_seq_nr, tvb, offset, 1, ENC_BIG_ENDIAN);
 
-            if (check_col(pinfo->cinfo, COL_INFO))
-            {
-                col_append_fstr(pinfo->cinfo, COL_INFO, "  seqno=%u", frame_seq_no);
-            }
+            col_append_fstr(pinfo->cinfo, COL_INFO, "  seqno=%u", frame_seq_no);
         }
 
         /* CmCH-PI */
-        proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
         /* MAC-d PDU Length (13 bits) */
         pdu_length = (tvb_get_ntohs(tvb, offset) >> 3);
-        proto_tree_add_item(tree, hf_fp_mac_d_pdu_len, tvb, offset, 2, FALSE);
+        proto_tree_add_item(tree, hf_fp_mac_d_pdu_len, tvb, offset, 2, ENC_BIG_ENDIAN);
         offset += 2;
 
         if ((p_fp_info->release == 6) ||
             (p_fp_info->release == 7))
         {
             /* Flush bit */
-            proto_tree_add_item(tree, hf_fp_flush, tvb, offset-1, 1, FALSE);
+            proto_tree_add_item(tree, hf_fp_flush, tvb, offset-1, 1, ENC_BIG_ENDIAN);
 
             /* FSN/DRT reset bit */
-            proto_tree_add_item(tree, hf_fp_fsn_drt_reset, tvb, offset-1, 1, FALSE);
+            proto_tree_add_item(tree, hf_fp_fsn_drt_reset, tvb, offset-1, 1, ENC_BIG_ENDIAN);
         }
 
 
-        /* Num of PDU */
+        /* Num of PDUs */
         number_of_pdus = tvb_get_guint8(tvb, offset);
-        proto_tree_add_item(tree, hf_fp_num_of_pdu, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_num_of_pdu, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
         /* User buffer size */
         user_buffer_size = tvb_get_ntohs(tvb, offset);
-        proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, FALSE);
+        proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, ENC_BIG_ENDIAN);
         offset += 2;
 
         /* MAC-d PDUs */
         offset = dissect_macd_pdu_data(tvb, pinfo, tree, offset, pdu_length,
                                        number_of_pdus);
 
-        if (check_col(pinfo->cinfo, COL_INFO))
-        {
-            col_append_fstr(pinfo->cinfo, COL_INFO, "  User-Buffer-Size=%u", user_buffer_size);
-        }
+        col_append_fstr(pinfo->cinfo, COL_INFO, "  %ux%u-bit PDUs  User-Buffer-Size=%u",
+                        number_of_pdus, pdu_length, user_buffer_size);
 
         /* Extra IEs (if there is room for them) */
         if (((p_fp_info->release == 6) ||
@@ -2654,7 +2940,7 @@ void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
         {
             int n;
             guint8 flags;
-            guint8 flag_bytes = 0;
+            /* guint8 flag_bytes = 0; */
 
             /* New IE flags */
             do
@@ -2670,12 +2956,12 @@ void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
 
                 /* Read next byte */
                 flags = tvb_get_guint8(tvb, offset);
-                flag_bytes++;
+                /* flag_bytes++; */
 
                 /* Dissect individual bits */
                 for (n=0; n < 8; n++)
                 {
-                    proto_tree_add_item(new_ie_flags_tree, hf_fp_hsdsch_new_ie_flag[n], tvb, offset, 1, FALSE);
+                    proto_tree_add_item(new_ie_flags_tree, hf_fp_hsdsch_new_ie_flag[n], tvb, offset, 1, ENC_BIG_ENDIAN);
                     if ((flags >> (7-n)) & 0x01)
                     {
                         ies_found++;
@@ -2694,7 +2980,7 @@ void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
                    but the description below it states that
                    it should depend upon the first bit.  The detailed description of
                    New IE flags doesn't agree, so treat as mandatory for now... */
-                proto_tree_add_item(tree, hf_fp_hsdsch_drt, tvb, offset, 2, FALSE);
+                proto_tree_add_item(tree, hf_fp_hsdsch_drt, tvb, offset, 2, ENC_BIG_ENDIAN);
                 offset += 2;
             }
         }
@@ -2710,23 +2996,20 @@ void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
 /* (introduced in Release 7)              */
 /* N.B. there is currently no support for */
 /* frame type 3 (IuR only?)               */
-void dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                                        int offset, struct fp_info *p_fp_info)
+static void dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                                               int offset, struct fp_info *p_fp_info)
 {
     gboolean is_control_frame;
 
     /* Header CRC */
-    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
 
     /* Frame Type */
     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
-    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
+    proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
 
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
-    }
+    col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
 
     if (is_control_frame)
     {
@@ -2748,55 +3031,51 @@ void dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto
         /********************************/
         /* HS-DCH type 2 data here      */
 
+        col_append_str(pinfo->cinfo, COL_INFO, "(ehs)");
+
         /* Frame Seq Nr (4 bits) */
         if ((p_fp_info->release == 6) ||
             (p_fp_info->release == 7))
         {
             guint8 frame_seq_no = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
-            proto_tree_add_item(tree, hf_fp_frame_seq_nr, tvb, offset, 1, FALSE);
+            proto_tree_add_item(tree, hf_fp_frame_seq_nr, tvb, offset, 1, ENC_BIG_ENDIAN);
 
-            if (check_col(pinfo->cinfo, COL_INFO))
-            {
-                col_append_fstr(pinfo->cinfo, COL_INFO, "  seqno=%u", frame_seq_no);
-            }
+            col_append_fstr(pinfo->cinfo, COL_INFO, "  seqno=%u", frame_seq_no);
         }
 
         /* CmCH-PI (4 bits) */
-        proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
         /* Total number of PDU blocks (5 bits) */
         number_of_pdu_blocks = (tvb_get_guint8(tvb, offset) >> 3);
-        proto_tree_add_item(tree, hf_fp_total_pdu_blocks, tvb, offset, 1, FALSE);
+        proto_tree_add_item(tree, hf_fp_total_pdu_blocks, tvb, offset, 1, ENC_BIG_ENDIAN);
 
         if (p_fp_info->release == 7)
         {
             /* Flush bit */
-            proto_tree_add_item(tree, hf_fp_flush, tvb, offset, 1, FALSE);
+            proto_tree_add_item(tree, hf_fp_flush, tvb, offset, 1, ENC_BIG_ENDIAN);
 
             /* FSN/DRT reset bit */
-            proto_tree_add_item(tree, hf_fp_fsn_drt_reset, tvb, offset, 1, FALSE);
+            proto_tree_add_item(tree, hf_fp_fsn_drt_reset, tvb, offset, 1, ENC_BIG_ENDIAN);
 
             /* DRT Indicator */
             drt_present = tvb_get_guint8(tvb, offset) & 0x01;
-            proto_tree_add_item(tree, hf_fp_drt_indicator, tvb, offset, 1, FALSE);
+            proto_tree_add_item(tree, hf_fp_drt_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
         }
         offset++;
 
         /* FACH Indicator flag */
-        fach_present = (tvb_get_guint8(tvb, offset) & 0x08) >> 7;
-        proto_tree_add_item(tree, hf_fp_fach_indicator, tvb, offset, 1, FALSE);
+        fach_present = (tvb_get_guint8(tvb, offset) & 0x80) >> 7;
+        proto_tree_add_item(tree, hf_fp_fach_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
         offset++;
 
         /* User buffer size */
         user_buffer_size = tvb_get_ntohs(tvb, offset);
-        proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, FALSE);
+        proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, ENC_BIG_ENDIAN);
         offset += 2;
 
-        if (check_col(pinfo->cinfo, COL_INFO))
-        {
-            col_append_fstr(pinfo->cinfo, COL_INFO, "  User-Buffer-Size=%u", user_buffer_size);
-        }
+        col_append_fstr(pinfo->cinfo, COL_INFO, "  User-Buffer-Size=%u", user_buffer_size);
 
 
         /********************************************************************/
@@ -2805,6 +3084,7 @@ void dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto
         {
             proto_item *pdu_block_header_ti;
             proto_tree *pdu_block_header_tree;
+            int        block_header_start_offset = offset;
 
             /* Add PDU block header subtree */
             pdu_block_header_ti = proto_tree_add_string_format(tree, hf_fp_hsdsch_pdu_block_header,
@@ -2817,7 +3097,7 @@ void dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto
             /* MAC-d/c PDU length in this block (11 bits) */
             proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_pdu_length_in_block, tvb,
                                         (offset*8) + ((n % 2) ? 4 : 0), 11,
-                                        &pdu_length[n], FALSE);
+                                        &pdu_length[n], ENC_BIG_ENDIAN);
             if ((n % 2) == 0)
                 offset++;
             else
@@ -2827,16 +3107,18 @@ void dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto
             /* # PDUs in this block (4 bits) */
             proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_pdus_in_block, tvb,
                                         (offset*8) + ((n % 2) ? 0 : 4), 4,
-                                        &no_of_pdus[n], FALSE);
-            if ((n % 2) == 0)
+                                        &no_of_pdus[n], ENC_BIG_ENDIAN);
+            if ((n % 2) == 0) {
                 offset++;
+            }
 
             /* Logical channel ID in block (4 bits) */
             proto_tree_add_bits_ret_val(pdu_block_header_tree, hf_fp_lchid, tvb,
                                         (offset*8) + ((n % 2) ? 4 : 0), 4,
-                                        &lchid[n], FALSE);
-            if ((n % 2) == 1)
+                                        &lchid[n], ENC_BIG_ENDIAN);
+            if ((n % 2) == 1) {
                 offset++;
+            }
             else {
                 if (n == (number_of_pdu_blocks-1)) {
                     /* Byte is padded out for last block */
@@ -2850,6 +3132,16 @@ void dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto
                                    (guint16)lchid[n],
                                    (guint16)no_of_pdus[n],
                                    (guint16)pdu_length[n]);
+
+            /* Set length of header tree item */
+            if (((n % 2) == 0) && (n < (number_of_pdu_blocks-1))) {
+                proto_item_set_len(pdu_block_header_ti,
+                                   offset - block_header_start_offset+1);
+            }
+            else {
+                proto_item_set_len(pdu_block_header_ti,
+                                   offset - block_header_start_offset);
+            }
         }
 
 
@@ -2858,18 +3150,18 @@ void dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto
         if (drt_present)
         {
             /* DRT */
-            proto_tree_add_item(tree, hf_fp_drt, tvb, offset, 2, FALSE);
+            proto_tree_add_item(tree, hf_fp_drt, tvb, offset, 2, ENC_BIG_ENDIAN);
             offset += 2;
         }
 
         if (fach_present)
         {
             /* H-RNTI: */
-            proto_tree_add_item(tree, hf_fp_hrnti, tvb, offset, 2, FALSE);
+            proto_tree_add_item(tree, hf_fp_hrnti, tvb, offset, 2, ENC_BIG_ENDIAN);
             offset += 2;
 
             /* RACH Measurement Result */
-            proto_tree_add_item(tree, hf_fp_rach_measurement_result, tvb, offset, 2, FALSE);
+            proto_tree_add_item(tree, hf_fp_rach_measurement_result, tvb, offset, 2, ENC_BIG_ENDIAN);
             offset++;
         }
 
@@ -2889,6 +3181,36 @@ void dissect_hsdsch_type_2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto
     }
 }
 
+static gboolean heur_dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+    struct fp_info *p_fp_info;
+
+    p_fp_info = p_get_proto_data(pinfo->fd, proto_fp);
+
+    /* if no FP info is present, assume this is not FP over UDP */
+    if (!p_fp_info) return FALSE;
+
+    /* if FP info is present, check that it really is an ethernet link */
+    if (p_fp_info->link_type != FP_Link_Ethernet) {
+        return FALSE;
+    }
+
+    /* remember 'lower' UDP layer port information */
+    if (!p_fp_info->srcport || !p_fp_info->destport) {
+        p_fp_info->srcport = pinfo->srcport;
+        p_fp_info->destport = pinfo->destport;
+    }
+
+    /* discriminate 'lower' UDP layer from 'user data' UDP layer
+     * (i.e. if an FP over UDP packet contains a user UDP packet */
+    if (p_fp_info->srcport != pinfo->srcport ||
+        p_fp_info->destport != pinfo->destport)
+        return FALSE;
+
+    /* assume this is FP */
+    dissect_fp(tvb, pinfo, tree);
+    return TRUE;
+}
 
 
 /*****************************/
@@ -2901,38 +3223,57 @@ void dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     struct fp_info   *p_fp_info;
 
     /* Append this protocol name rather than replace. */
-    if (check_col(pinfo->cinfo, COL_PROTOCOL))
-        col_set_str(pinfo->cinfo, COL_PROTOCOL, "FP");
+    col_set_str(pinfo->cinfo, COL_PROTOCOL, "FP");
 
     /* Create fp tree. */
-    ti = proto_tree_add_item(tree, proto_fp, tvb, offset, -1, FALSE);
+    ti = proto_tree_add_item(tree, proto_fp, tvb, offset, -1, ENC_NA);
     fp_tree = proto_item_add_subtree(ti, ett_fp);
 
+    top_level_tree = tree;
+
     /* Look for packet info! */
     p_fp_info = p_get_proto_data(pinfo->fd, proto_fp);
 
     /* Can't dissect anything without it... */
     if (p_fp_info == NULL)
     {
-        proto_item *ti =
-            proto_tree_add_text(fp_tree, tvb, offset, -1,
+        ti = proto_tree_add_text(fp_tree, tvb, offset, -1,
                                 "Can't dissect FP frame because no per-frame info was attached!");
         PROTO_ITEM_SET_GENERATED(ti);
         return;
     }
 
-    /* Show channel type in info column, tree */
-    if (check_col(pinfo->cinfo, COL_INFO))
-    {
-        col_add_str(pinfo->cinfo, COL_INFO,
-                    val_to_str(p_fp_info->channel,
-                               channel_type_vals,
-                               "Unknown channel type"));
+    /* Show release information */
+    if (preferences_show_release_info) {
+        proto_item *release_ti;
+        proto_tree *release_tree;
+        proto_item *temp_ti;
+
+        release_ti = proto_tree_add_item(fp_tree, hf_fp_release, tvb, 0, 0, ENC_NA);
+        PROTO_ITEM_SET_GENERATED(release_ti);
+        proto_item_append_text(release_ti, " R%u (%d/%d)",
+                               p_fp_info->release, p_fp_info->release_year, p_fp_info->release_month);
+        release_tree = proto_item_add_subtree(release_ti, ett_fp_release);
+
+        temp_ti = proto_tree_add_uint(release_tree, hf_fp_release_version, tvb, 0, 0, p_fp_info->release);
+        PROTO_ITEM_SET_GENERATED(temp_ti);
+
+        temp_ti = proto_tree_add_uint(release_tree, hf_fp_release_year, tvb, 0, 0, p_fp_info->release_year);
+        PROTO_ITEM_SET_GENERATED(temp_ti);
+
+        temp_ti = proto_tree_add_uint(release_tree, hf_fp_release_month, tvb, 0, 0, p_fp_info->release_month);
+        PROTO_ITEM_SET_GENERATED(temp_ti);
     }
+
+    /* Show channel type in info column, tree */
+    col_add_str(pinfo->cinfo, COL_INFO,
+                val_to_str_const(p_fp_info->channel,
+                                 channel_type_vals,
+                                 "Unknown channel type"));
     proto_item_append_text(ti, " (%s)",
-                           val_to_str(p_fp_info->channel,
-                                      channel_type_vals,
-                                      "Unknown channel type"));
+                           val_to_str_const(p_fp_info->channel,
+                                            channel_type_vals,
+                                            "Unknown channel type"));
 
     /* Add channel type as a generated field */
     ti = proto_tree_add_uint(fp_tree, hf_fp_channel_type, tvb, 0, 0, p_fp_info->channel);
@@ -2956,6 +3297,33 @@ void dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         return;
     }
 
+    /* Show DDI config info */
+    if (p_fp_info->no_ddi_entries > 0) {
+        int n;
+        proto_item *ddi_config_ti;
+        proto_tree *ddi_config_tree;
+
+        ddi_config_ti = proto_tree_add_string_format(fp_tree, hf_fp_ddi_config, tvb, offset, 0,
+                                                     "", "DDI Config (");
+        PROTO_ITEM_SET_GENERATED(ddi_config_ti);
+        ddi_config_tree = proto_item_add_subtree(ddi_config_ti, ett_fp_ddi_config);
+
+        /* Add each entry */
+        for (n=0; n < p_fp_info->no_ddi_entries; n++) {
+            proto_item_append_text(ddi_config_ti, "%s%u->%ubits",
+                                   (n==0) ? "" : "  ",
+                                   p_fp_info->edch_ddi[n], p_fp_info->edch_macd_pdu_size[n]);
+            ti = proto_tree_add_uint(ddi_config_tree, hf_fp_ddi_config_ddi, tvb, 0, 0,
+                                p_fp_info->edch_ddi[n]);
+            PROTO_ITEM_SET_GENERATED(ti);
+            ti = proto_tree_add_uint(ddi_config_tree, hf_fp_ddi_config_macd_pdu_size, tvb, 0, 0,
+                                p_fp_info->edch_macd_pdu_size[n]);
+            PROTO_ITEM_SET_GENERATED(ti);
+
+        }
+        proto_item_append_text(ddi_config_ti, ")");
+    }
+
     /*************************************/
     /* Dissect according to channel type */
     switch (p_fp_info->channel)
@@ -2990,6 +3358,15 @@ void dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
             dissect_bch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
             break;
         case CHANNEL_HSDSCH:
+            /* Show configured MAC HS-DSCH entity in use */
+            if (fp_tree)
+            {
+                proto_item *entity_ti;
+                entity_ti = proto_tree_add_uint(fp_tree, hf_fp_hsdsch_entity,
+                                                tvb, 0, 0,
+                                                p_fp_info->hsdsch_entity);
+                PROTO_ITEM_SET_GENERATED(entity_ti);
+            }
             switch (p_fp_info->hsdsch_entity) {
                 case entity_not_specified:
                 case hs:
@@ -3000,10 +3377,16 @@ void dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                     dissect_hsdsch_type_2_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
                     break;
                 default:
-                    /* ERROR */
+                    /* TODO: dissector error */
                     break;
             }
             break;
+        case CHANNEL_HSDSCH_COMMON:
+            /* TODO: */
+            break;
+        case CHANNEL_HSDSCH_COMMON_T3:
+            /* TODO: */
+            break;
         case CHANNEL_IUR_CPCHF:
             /* TODO: */
             break;
@@ -3014,7 +3397,9 @@ void dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
             dissect_iur_dsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
             break;
         case CHANNEL_EDCH:
-            dissect_e_dch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
+        case CHANNEL_EDCH_COMMON:
+            dissect_e_dch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info,
+                                       p_fp_info->channel == CHANNEL_EDCH_COMMON);
             break;
 
         default:
@@ -3027,10 +3412,34 @@ void proto_register_fp(void)
 {
     static hf_register_info hf[] =
     {
+        { &hf_fp_release,
+            { "Release",
+              "fp.release", FT_NONE, BASE_NONE, NULL, 0x0,
+              "Release information", HFILL
+            }
+        },
+        { &hf_fp_release_version,
+            { "Release Version",
+              "fp.release.version", FT_UINT8, BASE_DEC, NULL, 0x0,
+              "3GPP Release number", HFILL
+            }
+        },
+        { &hf_fp_release_year,
+            { "Release year",
+              "fp.release.year", FT_UINT16, BASE_DEC, NULL, 0x0,
+              NULL, HFILL
+            }
+        },
+        { &hf_fp_release_month,
+            { "Release month",
+              "fp.release.month", FT_UINT8, BASE_DEC, NULL, 0x0,
+              NULL, HFILL
+            }
+        },
         { &hf_fp_channel_type,
             { "Channel Type",
               "fp.channel-type", FT_UINT8, BASE_HEX, VALS(channel_type_vals), 0x0,
-              "Channel Type", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_division,
@@ -3045,16 +3454,36 @@ void proto_register_fp(void)
               "Link direction", HFILL
             }
         },
+        { &hf_fp_ddi_config,
+            { "DDI Config",
+              "fp.ddi-config", FT_STRING, BASE_NONE, NULL, 0x0,
+              "DDI Config (for E-DCH)", HFILL
+            }
+        },
+        { &hf_fp_ddi_config_ddi,
+            { "DDI",
+              "fp.ddi-config.ddi", FT_UINT8, BASE_DEC, NULL, 0x0,
+              NULL, HFILL
+            }
+        },
+        { &hf_fp_ddi_config_macd_pdu_size,
+            { "MACd PDU Size",
+              "fp.ddi-config.macd-pdu-size", FT_UINT16, BASE_DEC, NULL, 0x0,
+              NULL, HFILL
+            }
+        },
+
+
         { &hf_fp_header_crc,
             { "Header CRC",
               "fp.header-crc", FT_UINT8, BASE_HEX, NULL, 0xfe,
-              "Header CRC", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_ft,
             { "Frame Type",
               "fp.ft", FT_UINT8, BASE_HEX, VALS(data_control_vals), 0x01,
-              "Frame Type", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_cfn,
@@ -3083,13 +3512,13 @@ void proto_register_fp(void)
         },
         { &hf_fp_toa,
             { "ToA",
-              "fp.cfn-control", FT_INT16, BASE_DEC, NULL, 0x0,
+              "fp.toa", FT_INT16, BASE_DEC, NULL, 0x0,
               "Time of arrival (units are 125 microseconds)", HFILL
             }
         },
         { &hf_fp_tb,
             { "TB",
-              "fp.tb", FT_BYTES, BASE_HEX, NULL, 0x0,
+              "fp.tb", FT_BYTES, BASE_NONE, NULL, 0x0,
               "Transport Block", HFILL
             }
         },
@@ -3120,7 +3549,7 @@ void proto_register_fp(void)
         { &hf_fp_propagation_delay,
             { "Propagation Delay",
               "fp.propagation-delay", FT_UINT8, BASE_DEC, NULL, 0x0,
-              "Propagation Delay", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_dch_control_frame_type,
@@ -3138,13 +3567,13 @@ void proto_register_fp(void)
         { &hf_fp_quality_estimate,
             { "Quality Estimate",
               "fp.dch.quality-estimate", FT_UINT8, BASE_DEC, 0, 0x0,
-              "Quality Estimate", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_payload_crc,
             { "Payload CRC",
               "fp.payload-crc", FT_UINT16, BASE_HEX, 0, 0x0,
-              "Payload CRC", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_common_control_frame_type,
@@ -3204,7 +3633,7 @@ void proto_register_fp(void)
         { &hf_fp_received_sync_ul_timing_deviation,
             { "Received SYNC UL Timing Deviation",
               "fp.rx-sync-ul-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
-              "Received SYNC UL Timing Deviation", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_pch_pi,
@@ -3227,7 +3656,7 @@ void proto_register_fp(void)
         },
         { &hf_fp_transmit_power_level,
             { "Transmit Power Level",
-              "fp.transmit-power-level", FT_FLOAT, BASE_DEC, 0, 0x0,
+              "fp.transmit-power-level", FT_FLOAT, BASE_NONE, 0, 0x0,
               "Transmit Power Level (dB)", HFILL
             }
         },
@@ -3252,13 +3681,13 @@ void proto_register_fp(void)
         { &hf_fp_dch_e_rucch_flag,
             { "E-RUCCH Flag",
               "fp.common.control.e-rucch-flag", FT_UINT8, BASE_DEC, VALS(e_rucch_flag_vals), 0x0,
-              "E-RUCCH Flag", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_edch_header_crc,
             { "E-DCH Header CRC",
-              "fp.edch.header-crc", FT_UINT16, BASE_HEX, 0, 0xfef,
-              "E-DCH Header CRC", HFILL
+              "fp.edch.header-crc", FT_UINT16, BASE_HEX, 0, 0xfef0,
+              NULL, HFILL
             }
         },
         { &hf_fp_edch_fsn,
@@ -3281,14 +3710,14 @@ void proto_register_fp(void)
         },
         { &hf_fp_edch_subframe_number,
             { "Subframe number",
-              "fp.edch.subframe-number", FT_UINT8, BASE_DEC, 0, 0x07,
+              "fp.edch.subframe-number", FT_UINT8, BASE_DEC, 0, 0x0,
               "E-DCH Subframe number", HFILL
             }
         },
         { &hf_fp_edch_number_of_mac_es_pdus,
             { "Number of Mac-es PDUs",
               "fp.edch.number-of-mac-es-pdus", FT_UINT8, BASE_DEC, 0, 0xf0,
-              "Number of Mac-es PDUs", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_edch_ddi,
@@ -3312,7 +3741,7 @@ void proto_register_fp(void)
         { &hf_fp_edch_number_of_mac_d_pdus,
             { "Number of Mac-d PDUs",
               "fp.edch.number-of-mac-d-pdus", FT_UINT8, BASE_DEC, 0, 0x0,
-              "Number of Mac-d PDUs", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_edch_pdu_padding,
@@ -3330,9 +3759,80 @@ void proto_register_fp(void)
         { &hf_fp_edch_mac_es_pdu,
             { "MAC-es PDU",
               "fp.edch.mac-es-pdu", FT_NONE, BASE_NONE, NULL, 0x0,
-              "MAC-es PDU", HFILL
+              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, 0x0,
+              NULL, HFILL
+            }
+        },
+        { &hf_fp_edch_e_rnti,
+            { "E-RNTI",
+              "fp.edch.e-rnti", FT_UINT16, BASE_DEC, 0, 0x0,
+              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, VALS(lchid_vals), 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,
@@ -3366,13 +3866,13 @@ void proto_register_fp(void)
         { &hf_fp_drt_indicator,
             { "DRT Indicator",
               "fp.drt-indicator", FT_UINT8, BASE_DEC, 0, 0x01,
-              "DRT Indicator", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_fach_indicator,
             { "FACH Indicator",
               "fp.fach-indicator", FT_UINT8, BASE_DEC, 0, 0x80,
-              "FACH Indicator", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_total_pdu_blocks,
@@ -3384,25 +3884,25 @@ void proto_register_fp(void)
         { &hf_fp_drt,
             { "DRT",
               "fp.drt", FT_UINT16, BASE_DEC, 0, 0x0,
-              "DRT", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_hrnti,
             { "HRNTI",
               "fp.hrnti", FT_UINT16, BASE_DEC, 0, 0x0,
-              "HRNTI", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_rach_measurement_result,
             { "RACH Measurement Result",
-              "fp.rach-meansurement-result", FT_UINT16, BASE_DEC, 0, 0x0,
-              "RACH Measurement Result", HFILL
+              "fp.rach-measurement-result", FT_UINT16, BASE_DEC, 0, 0x0,
+              NULL, HFILL
             }
         },
         { &hf_fp_lchid,
             { "Logical Channel ID",
-              "fp.lchid", FT_UINT8, BASE_DEC, 0, 0x0,
-              "Logical Channel ID", HFILL
+              "fp.lchid", FT_UINT8, BASE_DEC, NULL, 0x0,
+              NULL, HFILL
             }
         },
         { &hf_fp_pdu_length_in_block,
@@ -3432,7 +3932,7 @@ void proto_register_fp(void)
         { &hf_fp_hsdsch_credits,
             { "HS-DSCH Credits",
               "fp.hsdsch-credits", FT_UINT16, BASE_DEC, 0, 0x0,
-              "HS-DSCH Credits", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_hsdsch_max_macd_pdu_len,
@@ -3450,7 +3950,7 @@ void proto_register_fp(void)
         { &hf_fp_hsdsch_interval,
             { "HS-DSCH Interval in milliseconds",
               "fp.hsdsch-interval", FT_UINT8, BASE_DEC, 0, 0x0,
-              "HS-DSCH Interval in milliseconds", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_hsdsch_calculated_rate,
@@ -3480,49 +3980,49 @@ void proto_register_fp(void)
         { &hf_fp_hsdsch_new_ie_flags,
             { "New IEs flags",
               "fp.hsdsch.new-ie-flags", FT_STRING, BASE_NONE, 0, 0x0,
-              "New IEs flags", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_hsdsch_new_ie_flag[0],
             { "DRT IE present",
               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x80,
-              "DRT IE present", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_hsdsch_new_ie_flag[1],
             { "New IE present",
               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x40,
-              "New IE present", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_hsdsch_new_ie_flag[2],
             { "New IE present",
               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x20,
-              "New IE present", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_hsdsch_new_ie_flag[3],
             { "New IE present",
               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x10,
-              "New IE present", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_hsdsch_new_ie_flag[4],
             { "New IE present",
               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x08,
-              "New IE present", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_hsdsch_new_ie_flag[5],
             { "New IE present",
               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x04,
-              "New IE present", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_hsdsch_new_ie_flag[6],
             { "New IE present",
               "fp.hsdsch.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x02,
-              "New IE present", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_hsdsch_new_ie_flag[7],
@@ -3537,6 +4037,12 @@ void proto_register_fp(void)
               "Delay Reference Time", HFILL
             }
         },
+        { &hf_fp_hsdsch_entity,
+            { "HS-DSCH Entity",
+              "fp.hsdsch.entity", FT_UINT8, BASE_DEC, VALS(hsdshc_mac_entity_vals), 0x0,
+              "Type of MAC entity for this HS-DSCH channel", HFILL
+            }
+        },
         { &hf_fp_timing_advance,
             { "Timing advance",
               "fp.timing-advance", FT_UINT8, BASE_DEC, 0, 0x3f,
@@ -3557,19 +4063,19 @@ void proto_register_fp(void)
         },
         { &hf_fp_mac_d_pdu,
             { "MAC-d PDU",
-              "fp.mac-d-pdu", FT_BYTES, BASE_HEX, NULL, 0x0,
-              "MAC-d PDU", HFILL
+              "fp.mac-d-pdu", FT_BYTES, BASE_NONE, NULL, 0x0,
+              NULL, HFILL
             }
         },
         { &hf_fp_data,
             { "Data",
-              "fp.data", FT_BYTES, BASE_HEX, NULL, 0x0,
-              "Data", HFILL
+              "fp.data", FT_BYTES, BASE_NONE, NULL, 0x0,
+              NULL, HFILL
             }
         },
         { &hf_fp_crcis,
             { "CRCIs",
-              "fp.crcis", FT_BYTES, BASE_HEX, NULL, 0x0,
+              "fp.crcis", FT_BYTES, BASE_NONE, NULL, 0x0,
               "CRC Indicators for uplink TBs", HFILL
             }
         },
@@ -3593,7 +4099,7 @@ void proto_register_fp(void)
         },
         { &hf_fp_ul_sir_target,
             { "UL_SIR_TARGET",
-              "fp.ul-sir-target", FT_FLOAT, BASE_DEC, 0, 0x0,
+              "fp.ul-sir-target", FT_FLOAT, BASE_NONE, 0, 0x0,
               "Value (in dB) of the SIR target to be used by the UL inner loop power control", HFILL
             }
         },
@@ -3624,37 +4130,37 @@ void proto_register_fp(void)
         { &hf_fp_code_number,
             { "Code number",
               "fp.code-number", FT_UINT8, BASE_DEC, NULL, 0x0,
-              "Code number", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_spreading_factor,
             { "Spreading factor",
               "fp.spreading-factor", FT_UINT8, BASE_DEC, VALS(spreading_factor_vals), 0xf0,
-              "Spreading factor", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_mc_info,
             { "MC info",
               "fp.mc-info", FT_UINT8, BASE_DEC, NULL, 0x0e,
-              "MC info", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_rach_new_ie_flags,
             { "New IEs flags",
               "fp.rach.new-ie-flags", FT_STRING, BASE_NONE, 0, 0x0,
-              "New IEs flags", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_rach_new_ie_flag_unused[0],
             { "New IE present",
               "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x80,
-              "New IE present", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_rach_new_ie_flag_unused[1],
             { "New IE present",
               "fp.rach.new-ie-flag", FT_UINT8, BASE_DEC, 0, 0x40,
-              "New IE present", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_rach_new_ie_flag_unused[2],
@@ -3690,55 +4196,55 @@ void proto_register_fp(void)
         { &hf_fp_rach_cell_portion_id_present,
             { "Cell portion ID present",
               "fp.rach.cell-portion-id-present", FT_UINT8, BASE_DEC, 0, 0x01,
-              "Cell portion ID present", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_rach_angle_of_arrival_present,
             { "Angle of arrival present",
               "fp.rach.angle-of-arrival-present", FT_UINT8, BASE_DEC, 0, 0x01,
-              "Angle of arrival present", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_rach_ext_propagation_delay_present,
             { "Ext Propagation Delay Present",
               "fp.rach.ext-propagation-delay-present", FT_UINT8, BASE_DEC, 0, 0x02,
-              "Ext Propagation Delay Present", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_rach_ext_rx_sync_ul_timing_deviation_present,
             { "Ext Received Sync UL Timing Deviation present",
               "fp.rach.ext-rx-sync-ul-timing-deviation-present", FT_UINT8, BASE_DEC, 0, 0x02,
-              "Ext Received Sync UL Timing Deviation present", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_rach_ext_rx_timing_deviation_present,
             { "Ext Rx Timing Deviation present",
               "fp.rach.ext-rx-timing-deviation-present", FT_UINT8, BASE_DEC, 0, 0x01,
-              "Ext Rx Timing Deviation present", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_cell_portion_id,
             { "Cell Portion ID",
               "fp.cell-portion-id", FT_UINT8, BASE_DEC, NULL, 0x3f,
-              "Cell Portion ID", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_ext_propagation_delay,
             { "Ext Propagation Delay",
               "fp.ext-propagation-delay", FT_UINT16, BASE_DEC, NULL, 0x03ff,
-              "Ext Propagation Delay", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_angle_of_arrival,
             { "Angle of Arrival",
               "fp.angle-of-arrival", FT_UINT16, BASE_DEC, NULL, 0x03ff,
-              "Angle of Arrival", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_ext_received_sync_ul_timing_deviation,
             { "Ext Received SYNC UL Timing Deviation",
               "fp.ext-received-sync-ul-timing-deviation", FT_UINT16, BASE_DEC, NULL, 0x1fff,
-              "Ext Received SYNC UL Timing Deviation", HFILL
+              NULL, HFILL
             }
         },
 
@@ -3746,25 +4252,25 @@ void proto_register_fp(void)
         { &hf_fp_radio_interface_parameter_update_flag[0],
             { "CFN valid",
               "fp.radio-interface-param.cfn-valid", FT_UINT16, BASE_DEC, 0, 0x0001,
-              "CFN valid", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_radio_interface_parameter_update_flag[1],
             { "TPC PO valid",
               "fp.radio-interface-param.tpc-po-valid", FT_UINT16, BASE_DEC, 0, 0x0002,
-              "TPC PO valid", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_radio_interface_parameter_update_flag[2],
             { "DPC mode valid",
               "fp.radio-interface-param.dpc-mode-valid", FT_UINT16, BASE_DEC, 0, 0x0004,
-              "DPC mode valid", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_radio_interface_parameter_update_flag[3],
             { "RL sets indicator valid",
               "fp.radio-interface_param.rl-sets-indicator-valid", FT_UINT16, BASE_DEC, 0, 0x0020,
-              "RL sets indicator valid", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_radio_interface_parameter_update_flag[4],
@@ -3782,13 +4288,13 @@ void proto_register_fp(void)
         { &hf_fp_tpc_po,
             { "TPC PO",
               "fp.tpc-po", FT_UINT8, BASE_DEC, NULL, 0x1f,
-              "TPC PO", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_multiple_rl_set_indicator,
             { "Multiple RL sets indicator",
               "fp.multiple-rl-sets-indicator", FT_UINT8, BASE_DEC, NULL, 0x80,
-              "Multiple RL sets indicator", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_max_ue_tx_pow,
@@ -3800,31 +4306,31 @@ void proto_register_fp(void)
         { &hf_fp_congestion_status,
             { "Congestion Status",
               "fp.congestion-status", FT_UINT8, BASE_DEC, VALS(congestion_status_vals), 0x0,
-              "Congestion Status", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_e_rucch_present,
             { "E-RUCCH Present",
               "fp.erucch-present", FT_UINT8, BASE_DEC, NULL, 0x0,
-              "E-RUCCH Present", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_extended_bits_present,
             { "Extended Bits Present",
               "fp.extended-bits-present", FT_UINT8, BASE_DEC, NULL, 0x0,
-              "Extended Bits Present", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_extended_bits,
             { "Extended Bits",
               "fp.extended-bits", FT_UINT8, BASE_HEX, NULL, 0x0,
-              "Extended Bits", HFILL
+              NULL, HFILL
             }
         },
         { &hf_fp_spare_extension,
             { "Spare Extension",
               "fp.spare-extension", FT_NONE, BASE_NONE, NULL, 0x0,
-              "Spare Extension", HFILL
+              NULL, HFILL
             }
         },
 
@@ -3836,13 +4342,20 @@ void proto_register_fp(void)
         &ett_fp,
         &ett_fp_data,
         &ett_fp_crcis,
+        &ett_fp_ddi_config,
         &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
+        &ett_fp_hsdsch_pdu_block_header,
+        &ett_fp_release
     };
 
+    module_t *fp_module;
+
     /* Register protocol. */
     proto_fp = proto_register_protocol("FP", "FP", "fp");
     proto_register_field_array(proto_fp, hf, array_length(hf));
@@ -3850,10 +4363,34 @@ void proto_register_fp(void)
 
     /* Allow other dissectors to find this one by name. */
     register_dissector("fp", dissect_fp, proto_fp);
+
+    /* Preferences */
+    fp_module = prefs_register_protocol(proto_fp, NULL);
+
+    /* Determines whether release information should be displayed */
+    prefs_register_bool_preference(fp_module, "show_release_info",
+                                   "Show reported release info",
+                                   "Show reported release info",
+                                   &preferences_show_release_info);
+
+    /* Determines whether MAC dissector should be called for payloads */
+    prefs_register_bool_preference(fp_module, "call_mac",
+                                   "Call MAC dissector for payloads",
+                                   "Call MAC dissector for payloads",
+                                   &preferences_call_mac_dissectors);
+
 }
 
 
 void proto_reg_handoff_fp(void)
 {
+    mac_fdd_rach_handle = find_dissector("mac.fdd.rach");
+    mac_fdd_fach_handle = find_dissector("mac.fdd.fach");
+    mac_fdd_pch_handle = find_dissector("mac.fdd.pch");
+    mac_fdd_dch_handle = find_dissector("mac.fdd.dch");
+    mac_fdd_edch_handle = find_dissector("mac.fdd.edch");
+    mac_fdd_hsdsch_handle = find_dissector("mac.fdd.hsdsch");
+
+    heur_dissector_add("udp", heur_dissect_fp, proto_fp);
 }