Add support for R6 HSDPA data 'new IEs' (the spec seems not be be very clear...).
[obnox/wireshark/wip.git] / epan / dissectors / packet-umts_fp.c
1 /* Routines for UMTS FP disassembly
2  *
3  * Martin Mathieson
4  *
5  * $Id: packet-fp.c 18196 2006-05-21 04:49:01Z sahlberg $
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <epan/packet.h>
31 #include <epan/expert.h>
32
33 #include "packet-umts_fp.h"
34
35 /* TODO:
36    - remaining message types
37    - verify header & payload CRCs
38    - look for (and report as expert info) spare extension bytes
39 */
40
41 /* Initialize the protocol and registered fields. */
42 int proto_fp = -1;
43
44 static int hf_fp_channel_type = -1;
45 static int hf_fp_direction = -1;
46 static int hf_fp_header_crc = -1;
47 static int hf_fp_ft = -1;
48 static int hf_fp_cfn = -1;
49 static int hf_fp_pch_cfn = -1;
50 static int hf_fp_pch_toa = -1;
51 static int hf_fp_cfn_control = -1;
52 static int hf_fp_toa = -1;
53 static int hf_fp_tfi = -1;
54 static int hf_fp_usch_tfi = -1;
55 static int hf_fp_propagation_delay = -1;
56 static int hf_fp_tb = -1;
57 static int hf_fp_received_sync_ul_timing_deviation = -1;
58 static int hf_fp_pch_pi = -1;
59 static int hf_fp_pch_tfi = -1;
60 static int hf_fp_fach_tfi = -1;
61 static int hf_fp_transmit_power_level = -1;
62 static int hf_fp_paging_indication_bitmap = -1;
63 static int hf_fp_pdsch_set_id = -1;
64 static int hf_fp_rx_timing_deviation = -1;
65 static int hf_fp_dch_control_frame_type = -1;
66 static int hf_fp_dch_rx_timing_deviation = -1;
67 static int hf_fp_quality_estimate = -1;
68 static int hf_fp_payload_crc = -1;
69 static int hf_fp_edch_header_crc = -1;
70 static int hf_fp_edch_fsn = -1;
71 static int hf_fp_edch_subframe = -1;
72 static int hf_fp_edch_number_of_subframes = -1;
73 static int hf_fp_edch_harq_retransmissions = -1;
74 static int hf_fp_edch_subframe_number = -1;
75 static int hf_fp_edch_number_of_mac_es_pdus = -1;
76 static int hf_fp_edch_ddi = -1;
77 static int hf_fp_edch_subframe_header = -1;
78 static int hf_fp_edch_number_of_mac_d_pdus = -1;
79 static int hf_fp_edch_pdu_padding = -1;
80 static int hf_fp_edch_tsn = -1;
81 static int hf_fp_edch_mac_es_pdu = -1;
82 static int hf_fp_cmch_pi = -1;
83 static int hf_fp_user_buffer_size = -1;
84 static int hf_fp_hsdsch_credits = -1;
85 static int hf_fp_hsdsch_max_macd_pdu_len = -1;
86 static int hf_fp_hsdsch_interval = -1;
87 static int hf_fp_hsdsch_repetition_period = -1;
88 static int hf_fp_hsdsch_data_padding = -1;
89 static int hf_fp_hsdsch_new_ie_flags[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
90 static int hf_fp_hsdsch_drt = -1;
91 static int hf_fp_timing_advance = -1;
92 static int hf_fp_num_of_pdu = -1;
93 static int hf_fp_mac_d_pdu_len = -1;
94 static int hf_fp_mac_d_pdu = -1;
95 static int hf_fp_data = -1;
96 static int hf_fp_crcis = -1;
97 static int hf_fp_crci[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
98 static int hf_fp_common_control_frame_type = -1;
99 static int hf_fp_t1 = -1;
100 static int hf_fp_t2 = -1;
101 static int hf_fp_t3 = -1;
102 static int hf_fp_ul_sir_target = -1;
103
104 /* Subtrees. */
105 static int ett_fp = -1;
106 static int ett_fp_data = -1;
107 static int ett_fp_crcis = -1;
108 static int ett_fp_edch_subframe_header = -1;
109 static int ett_fp_edch_subframe = -1;
110
111
112 /* E-DCH channel header information */
113 struct subframe_info
114 {
115     guint8  subframe_number;
116     guint8  number_of_mac_es_pdus;
117     guint8  ddi[64];
118     guint16 number_of_mac_d_pdus[64];
119 };
120
121
122 static const value_string channel_type_vals[] =
123 {
124     { CHANNEL_RACH_FDD,     "RACH_FDD" },
125     { CHANNEL_RACH_TDD,     "RACH_TDD" },
126     { CHANNEL_FACH_FDD,     "FACH_FDD" },
127     { CHANNEL_FACH_TDD,     "FACH_TDD" },
128     { CHANNEL_DSCH_FDD,     "DSCH_FDD" },
129     { CHANNEL_DSCH_TDD,     "DSCH_TDD" },
130     { CHANNEL_USCH_TDD_384, "USCH_TDD_384" },
131     { CHANNEL_USCH_TDD_128, "USCH_TDD_128" },
132     { CHANNEL_PCH,          "PCH" },
133     { CHANNEL_CPCH,         "CPCH" },
134     { CHANNEL_BCH,          "BCH" },
135     { CHANNEL_DCH,          "DCH" },
136     { CHANNEL_HSDSCH,       "HSDSCH" },
137     { CHANNEL_IUR_CPCHF,    "IUR CPCHF" },
138     { CHANNEL_IUR_FACH,     "IUR FACH" },
139     { CHANNEL_IUR_DSCH,     "IUR DSCH" },
140     { CHANNEL_EDCH,         "EDCH" },
141     { CHANNEL_RACH_TDD_128, "RACH_TDD_128" },
142     { 0, NULL }
143 };
144
145 static const value_string data_control_vals[] = {
146     { 0,   "Data" },
147     { 1,   "Control" },
148     { 0,   NULL },
149 };
150
151 static const value_string direction_vals[] = {
152     { 0,   "Downlink" },
153     { 1,   "Uplink" },
154     { 0,   NULL },
155 };
156
157 static const value_string crci_vals[] = {
158     { 0,   "Correct" },
159     { 1,   "Not correct" },
160     { 0,   NULL },
161 };
162
163 static const value_string paging_indication_vals[] = {
164     { 0,   "no PI-bitmap in payload" },
165     { 1,   "PI-bitmap in payload" },
166     { 0,   NULL },
167 };
168
169
170 /* DCH control types */
171 #define DCH_OUTER_LOOP_POWER_CONTROL            1
172 #define DCH_TIMING_ADJUSTMENT                   2
173 #define DCH_DL_SYNCHRONISATION                  3
174 #define DCH_UL_SYNCHRONISATION                  4
175
176 #define DCH_DL_NODE_SYNCHRONISATION             6
177 #define DCH_UL_NODE_SYNCHRONISATION             7
178 #define DCH_RX_TIMING_DEVIATION                 8
179 #define DCH_RADIO_INTERFACE_PARAMETER_UPDATE    9
180 #define DCH_TIMING_ADVANCE                      10
181 #define DCH_TNL_CONGESTION_INDICATION           11
182
183 static const value_string dch_control_frame_type_vals[] = {
184     { DCH_OUTER_LOOP_POWER_CONTROL,         "OUTER LOOP POWER CONTROL" },
185     { DCH_TIMING_ADJUSTMENT,                "TIMING ADJUSTMENT" },
186     { DCH_DL_SYNCHRONISATION,               "DL SYNCHRONISATION" },
187     { DCH_UL_SYNCHRONISATION,               "UL SYNCHRONISATION" },
188     { 5,                                    "Reserved Value" },
189     { DCH_DL_NODE_SYNCHRONISATION,          "DL NODE SYNCHRONISATION" },
190     { DCH_UL_NODE_SYNCHRONISATION,          "UL NODE SYNCHRONISATION" },
191     { DCH_RX_TIMING_DEVIATION,              "RX TIMING DEVIATION" },
192     { DCH_RADIO_INTERFACE_PARAMETER_UPDATE, "RADIO INTERFACE PARAMETER UPDATE" },
193     { DCH_TIMING_ADVANCE,                   "TIMING ADVANCE" },
194     { DCH_TNL_CONGESTION_INDICATION,        "TNL CONGESTION INDICATION" },
195     { 0,   NULL },
196 };
197
198
199 /* Common channel control types */
200 #define COMMON_OUTER_LOOP_POWER_CONTROL         1
201 #define COMMON_TIMING_ADJUSTMENT                2
202 #define COMMON_DL_SYNCHRONISATION               3
203 #define COMMON_UL_SYNCHRONISATION               4
204
205 #define COMMON_DL_NODE_SYNCHRONISATION          6
206 #define COMMON_UL_NODE_SYNCHRONISATION          7
207 #define COMMON_DYNAMIC_PUSCH_ASSIGNMENT         8
208 #define COMMON_TIMING_ADVANCE                   9
209 #define COMMON_HS_DSCH_Capacity_Request         10
210 #define COMMON_HS_DSCH_Capacity_Allocation      11
211
212 static const value_string common_control_frame_type_vals[] = {
213     { COMMON_OUTER_LOOP_POWER_CONTROL,         "OUTER LOOP POWER CONTROL" },
214     { COMMON_TIMING_ADJUSTMENT,                "TIMING ADJUSTMENT" },
215     { COMMON_DL_SYNCHRONISATION,               "DL SYNCHRONISATION" },
216     { COMMON_UL_SYNCHRONISATION,               "UL SYNCHRONISATION" },
217     { 5,                                       "Reserved Value" },
218     { COMMON_DL_NODE_SYNCHRONISATION,          "DL NODE SYNCHRONISATION" },
219     { COMMON_UL_NODE_SYNCHRONISATION,          "UL NODE SYNCHRONISATION" },
220     { COMMON_DYNAMIC_PUSCH_ASSIGNMENT,         "DYNAMIC PUSCH ASSIGNMENT" },
221     { COMMON_TIMING_ADVANCE,                   "TIMING ADVANCE" },
222     { COMMON_HS_DSCH_Capacity_Request,         "HS-DSCH Capacity Request" },
223     { COMMON_HS_DSCH_Capacity_Allocation,      "HS-DSCH Capacity Allocation" },
224     { 0,   NULL },
225 };
226
227 /* Dissect message parts */
228 static int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
229                            int offset, struct _fp_info *p_fp_info, int *num_tbs);
230 static int dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
231                                  int offset, guint16 length, guint8 number_of_pdus);
232 static int dissect_crci_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
233                              int num_tbs, int offset);
234
235 /* Dissect common control messages */
236 static void dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
237                                              int offset, struct _fp_info *p_fp_info);
238 static void dissect_common_dl_node_synchronisation(packet_info *pinfo, proto_tree *tree,
239                                                    tvbuff_t *tvb, int offset);
240 static void dissect_common_ul_node_synchronisation(packet_info *pinfo, proto_tree *tree,
241                                                    tvbuff_t *tvb, int offset);
242 static void dissect_common_dl_syncronisation(packet_info *pinfo, proto_tree *tree,
243                                              tvbuff_t *tvb, int offset,
244                                              struct _fp_info *p_fp_info);
245 static void dissect_common_ul_syncronisation(packet_info *pinfo, proto_tree *tree,
246                                              tvbuff_t *tvb, int offset,
247                                              struct _fp_info *p_fp_info);
248 static void dissect_common_timing_advance(proto_tree *tree, tvbuff_t *tvb, int offset);
249 static void dissect_hsdpa_capacity_request(packet_info *pinfo, proto_tree *tree,
250                                            tvbuff_t *tvb, int offset);
251 static void dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
252                                               tvbuff_t *tvb, int offset);
253 static void dissect_common_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
254                                    int offset, struct _fp_info *p_fp_info);
255
256 /* Dissect common channel types */
257 static void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
258                                       int offset, struct _fp_info *p_fp_info);
259 static void dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
260                                       int offset, struct _fp_info *p_fp_info);
261 static void dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
262                                       int offset, struct _fp_info *p_fp_info);
263 static void dissect_usch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
264                                       int offset, struct _fp_info *p_fp_info);
265 static void dissect_pch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
266                                      int offset, struct _fp_info *p_fp_info);
267 static void dissect_iur_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
268                                           int offset, struct _fp_info *p_fp_info _U_);
269 static void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
270                                         int offset, struct _fp_info *p_fp_info);
271
272
273 /* Dissect DCH control messages */
274 static void dissect_dch_timing_adjustment(proto_tree *tree, packet_info *pinfo,
275                                           tvbuff_t *tvb, int offset);
276 static void dissect_dch_rx_timing_deviation(proto_tree *tree, tvbuff_t *tvb, int offset);
277 static void dissect_dch_dl_synchronisation(proto_tree *tree, packet_info *pinfo,
278                                            tvbuff_t *tvb, int offset);
279 static void dissect_dch_ul_synchronisation(proto_tree *tree, packet_info *pinfo,
280                                            tvbuff_t *tvb, int offset);
281 static void dissect_dch_dl_node_synchronisation(proto_tree *tree, packet_info *pinfo,
282                                                 tvbuff_t *tvb, int offset);
283 static void dissect_dch_ul_node_synchronisation(proto_tree *tree, packet_info *pinfo,
284                                                 tvbuff_t *tvb, int offset);
285
286
287 /* Dissect a DCH channel */
288 static void dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
289                                      int offset, struct _fp_info *p_fp_info);
290
291 /* Dissect dedicated channels */
292 static void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
293                                 int offset, struct _fp_info *p_fp_info);
294 static void dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
295
296 void proto_register_fp(void);
297 void proto_reg_handoff_fp(void);
298
299
300
301
302 /* Dissect the TBs of a data frame */
303 int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
304                     int offset, struct _fp_info *p_fp_info, int *num_tbs)
305 {
306     int chan;
307     int bit_offset = 0;
308     guint data_bits = 0;
309     proto_item *ti;
310     proto_tree *data_tree;
311
312     /* Add data subtree */
313     ti =  proto_tree_add_string_format(tree, hf_fp_data, tvb, offset, 0,
314                                        "",
315                                        "TB data for %u chans",
316                                        p_fp_info->num_chans);
317     data_tree = proto_item_add_subtree(ti, ett_fp_data);
318
319
320     /* Now for the TB data */
321     for (chan=0; chan < p_fp_info->num_chans; chan++)
322     {
323         int n;
324         for (n=0; n < p_fp_info->chan_num_tbs[chan]; n++)
325         {
326             proto_item *ti;
327             ti = proto_tree_add_item(data_tree, hf_fp_tb, tvb,
328                                      offset + (bit_offset/8),
329                                      ((bit_offset % 8) + p_fp_info->chan_tf_size[chan] + 7) / 8,
330                                      FALSE);
331             proto_item_append_text(ti, " (chan %u, tb %u, %u bits)",
332                                    chan+1, n+1, p_fp_info->chan_tf_size[chan]);
333             (*num_tbs)++;
334
335             /* Advance bit offset */
336             bit_offset += p_fp_info->chan_tf_size[chan];
337             data_bits += p_fp_info->chan_tf_size[chan];
338
339             /* Pad out to next byte */
340             if (bit_offset % 8)
341             {
342                 bit_offset += (8 - (bit_offset % 8));
343             }
344         }
345     }
346
347     if (check_col(pinfo->cinfo, COL_INFO))
348     {
349         col_append_fstr(pinfo->cinfo, COL_INFO, "(%u bits in %u tbs)",
350                         data_bits, *num_tbs);
351     }
352
353     /* Data tree should cover entire length */
354     proto_item_set_len(data_tree, bit_offset/8);
355     proto_item_append_text(ti, " (total %u tbs)", *num_tbs);
356
357     /* Move offset past TBs (we know its already padded out to next byte) */
358     offset += (bit_offset / 8);
359
360     return offset;
361 }
362
363
364 /* Dissect the MAC-d PDUs of an HS-DSCH frame */
365 int dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
366                           int offset, guint16 length, guint8 number_of_pdus)
367 {
368     int pdu;
369     int bit_offset = 0;
370     proto_item *ti;
371     proto_tree *data_tree;
372
373     /* Add data subtree */
374     ti =  proto_tree_add_string_format(tree, hf_fp_data, tvb, offset, 0,
375                                        "",
376                                        "%u MAC-d PDUs of %u bits",
377                                        number_of_pdus,
378                                        length);
379     data_tree = proto_item_add_subtree(ti, ett_fp_data);
380
381     /* Now for the PDUs */
382     for (pdu=0; pdu < number_of_pdus; pdu++)
383     {
384         proto_item *ti;
385
386         /* Show 4 bits padding at start of PDU */
387         proto_tree_add_item(data_tree, hf_fp_hsdsch_data_padding, tvb, offset+(bit_offset/8), 1, FALSE);
388
389         /* Data bytes! */
390         ti = proto_tree_add_item(data_tree, hf_fp_mac_d_pdu, tvb,
391                                  offset + (bit_offset/8),
392                                  ((bit_offset % 8) + length + 7) / 8,
393                                  FALSE);
394         proto_item_append_text(ti, " (PDU %u)", pdu+1);
395
396         /* Advance bit offset */
397         bit_offset += length;
398
399         /* Pad out to next byte */
400         if (bit_offset % 8)
401         {
402             bit_offset += (8 - (bit_offset % 8));
403         }
404     }
405
406     /* Data tree should cover entire length */
407     proto_item_set_len(data_tree, bit_offset/8);
408
409     /* Move offset past PDUs (we know its already padded out to next byte) */
410     offset += (bit_offset / 8);
411
412     /* Show summary in info column */
413     if (check_col(pinfo->cinfo, COL_INFO))
414     {
415         col_append_fstr(pinfo->cinfo, COL_INFO, "   %u PDUs of %u bits",
416                         number_of_pdus, length);
417     }
418
419     return offset;
420 }
421
422
423 /* Dissect CRCI bits (uplink) */
424 int dissect_crci_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
425                       int num_tbs, int offset)
426 {
427     int n;
428     proto_item *ti;
429     proto_tree *crcis_tree;
430     guint errors = 0;
431
432     /* Add CRCIs subtree */
433     ti =  proto_tree_add_string_format(tree, hf_fp_crcis, tvb, offset, 0,
434                                        "",
435                                        "CRCI bits for %u tbs",
436                                        num_tbs);
437     crcis_tree = proto_item_add_subtree(ti, ett_fp_crcis);
438
439     /* CRCIs */
440     for (n=0; n < num_tbs; n++)
441     {
442         int bit = (tvb_get_guint8(tvb, offset+(n/8)) >> (7-(n%8))) & 0x01;
443         proto_tree_add_item(crcis_tree, hf_fp_crci[n%8], tvb, offset+(n/8),
444                             1, FALSE);
445
446         if (bit == 1)
447         {
448             errors++;
449             expert_add_info_format(pinfo, ti,
450                                    PI_CHECKSUM, PI_WARN,
451                                    "CRCI error bit set for TB %u", n+1);
452         }
453     }
454
455     /* Highlight range of bytes covered by indicator bits */
456     proto_item_set_len(ti, (num_tbs+7) / 8);
457
458     /* Show error count in root text */
459     proto_item_append_text(ti, " (%u errors)", errors);
460
461     offset += ((num_tbs+7) / 8);
462     return offset;
463 }
464
465
466
467 /***********************************************************/
468 /* Common control message types                            */
469
470 void dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
471                                       int offset, struct _fp_info *p_fp_info)
472 {
473     if (p_fp_info->channel != CHANNEL_PCH)
474     {
475         guint8 cfn;
476         gint16 toa;
477
478         /* CFN control */
479         cfn = tvb_get_guint8(tvb, offset);
480         proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
481         offset++;
482
483         /* ToA */
484         toa = tvb_get_ntohs(tvb, offset);
485         proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, FALSE);
486         offset++;
487
488         if (check_col(pinfo->cinfo, COL_INFO))
489         {
490             col_append_fstr(pinfo->cinfo, COL_INFO, "   CFN=%u, ToA=%d", cfn, toa);
491         }
492     }
493     else
494     {
495         guint16 cfn;
496         gint32 toa;
497
498         /* PCH CFN is 12 bits */
499         cfn = (tvb_get_ntohs(tvb, offset) >> 4);
500         proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, FALSE);
501         offset += 2;
502
503         /* 4 bits of padding follow... */
504
505         /* 20 bits of ToA (followed by 4 padding bits) */
506         toa = ((int)(tvb_get_ntoh24(tvb, offset) << 8)) / 4096;
507         proto_tree_add_int(tree, hf_fp_pch_toa, tvb, offset, 3, toa);
508
509         if (check_col(pinfo->cinfo, COL_INFO))
510         {
511             col_append_fstr(pinfo->cinfo, COL_INFO, "   CFN=%u, ToA=%d", cfn, toa);
512         }
513     }
514 }
515
516 void dissect_common_dl_node_synchronisation(packet_info *pinfo, proto_tree *tree,
517                                             tvbuff_t *tvb, int offset)
518 {
519     /* T1 */
520     guint32 t1 = tvb_get_ntoh24(tvb, offset);
521     proto_tree_add_item(tree, hf_fp_t1, tvb, offset, 3, FALSE);
522
523     if (check_col(pinfo->cinfo, COL_INFO))
524     {
525         col_append_fstr(pinfo->cinfo, COL_INFO, "   T1=%u", t1);
526     }
527 }
528
529 void dissect_common_ul_node_synchronisation(packet_info *pinfo, proto_tree *tree,
530                                             tvbuff_t *tvb, int offset)
531 {
532     guint32 t1, t2, t3;
533
534     /* T1 */
535     t1 = tvb_get_ntoh24(tvb, offset);
536     proto_tree_add_item(tree, hf_fp_t1, tvb, offset, 3, FALSE);
537     offset += 3;
538
539     /* T2 */
540     t2 = tvb_get_ntoh24(tvb, offset);
541     proto_tree_add_item(tree, hf_fp_t2, tvb, offset, 3, FALSE);
542     offset += 3;
543
544     /* T3 */
545     t3 = tvb_get_ntoh24(tvb, offset);
546     proto_tree_add_item(tree, hf_fp_t3, tvb, offset, 3, FALSE);
547     offset += 3;
548
549     if (check_col(pinfo->cinfo, COL_INFO))
550     {
551         col_append_fstr(pinfo->cinfo, COL_INFO, "   T1=%u T2=%u, T3=%u",
552                         t1, t2, t3);
553     }
554 }
555
556 void dissect_common_dl_syncronisation(packet_info *pinfo, proto_tree *tree,
557                                       tvbuff_t *tvb, int offset, struct _fp_info *p_fp_info)
558 {
559     guint16 cfn;
560
561     if (p_fp_info->channel != CHANNEL_PCH)
562     {
563         /* CFN control */
564         cfn = tvb_get_guint8(tvb, offset);
565         proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
566     }
567     else
568     {
569         /* PCH CFN is 12 bits */
570         cfn = (tvb_get_ntohs(tvb, offset) >> 4);
571         proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, FALSE);
572
573         /* 4 bits of padding follow... */
574     }
575
576     if (check_col(pinfo->cinfo, COL_INFO))
577     {
578         col_append_fstr(pinfo->cinfo, COL_INFO, "   CFN=%u", cfn);
579     }
580 }
581
582 void dissect_common_ul_syncronisation(packet_info *pinfo, proto_tree *tree,
583                                       tvbuff_t *tvb, int offset, struct _fp_info *p_fp_info)
584 {
585     dissect_common_timing_adjustment(pinfo, tree, tvb, offset, p_fp_info);
586 }
587
588 void dissect_common_timing_advance(proto_tree *tree, tvbuff_t *tvb, int offset)
589 {
590     guint8 timing_advance;
591
592     /* CFN control */
593     proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
594     offset++;
595
596     /* Timing Advance */
597     timing_advance = (tvb_get_guint8(tvb, offset) & 0x3f);
598     proto_tree_add_uint(tree, hf_fp_timing_advance, tvb, offset, 1, timing_advance*4);
599     offset++;
600 }
601
602 void dissect_hsdpa_capacity_request(packet_info *pinfo, proto_tree *tree,
603                                     tvbuff_t *tvb, int offset)
604 {
605     guint8 priority;
606     guint16 user_buffer_size;
607
608     /* CmCH-PI */
609     priority = (tvb_get_guint8(tvb, offset) & 0x0f);
610     proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, FALSE);
611     offset++;
612
613     /* User buffer size */
614     user_buffer_size = tvb_get_ntohs(tvb, offset);
615     proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, FALSE);
616     offset += 2;
617
618     if (check_col(pinfo->cinfo, COL_INFO))
619     {
620         col_append_fstr(pinfo->cinfo, COL_INFO, "      CmCH-PI=%u  User-Buffer-Size=%u",
621                         priority, user_buffer_size);
622     }
623
624     /* TODO: Spare extension may follow */
625 }
626
627 void dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
628                                        tvbuff_t *tvb, int offset)
629 {
630     proto_item *ti;
631     guint16 max_pdu_length;
632     guint8 repetition_period;
633     guint8 interval;
634     guint16 credits;
635
636     /* CmCH-PI */
637     proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, FALSE);
638     offset++;
639
640     /* Max MAC-d PDU length (13 bits) */
641     max_pdu_length = (tvb_get_ntohs(tvb, offset) >> 3);
642     proto_tree_add_item(tree, hf_fp_hsdsch_max_macd_pdu_len, tvb, offset, 2, FALSE);
643     offset++;
644
645     /* HS-DSCH credits (11 bits) */
646     credits = (tvb_get_ntohs(tvb, offset) & 0x07ff);
647     ti = proto_tree_add_item(tree, hf_fp_hsdsch_credits, tvb, offset, 2, FALSE);
648     offset += 2;
649     if (credits == 0)
650     {
651         proto_item_append_text(ti, " (stop transmission)");
652     }
653     if (credits == 2047)
654     {
655         proto_item_append_text(ti, " (unlimited)");
656     }
657
658     /* HS-DSCH Interval */
659     interval = tvb_get_guint8(tvb, offset);
660     ti = proto_tree_add_uint(tree, hf_fp_hsdsch_interval, tvb, offset, 1, interval*10);
661     offset++;
662     if (interval == 0)
663     {
664         proto_item_append_text(ti, " (none of the credits shall be used)");
665     }
666
667     /* HS-DSCH Repetition period */
668     repetition_period = tvb_get_guint8(tvb, offset);
669     ti = proto_tree_add_item(tree, hf_fp_hsdsch_repetition_period, tvb, offset, 1, FALSE);
670     offset++;
671     if (repetition_period == 0)
672     {
673         proto_item_append_text(ti, " (unlimited repetition period)");
674     }
675
676     if (check_col(pinfo->cinfo, COL_INFO))
677     {
678         col_append_fstr(pinfo->cinfo, COL_INFO,
679                         "   Max-PDU-len=%u  Credits=%u  Interval=%u  Rep-Period=%u",
680                         max_pdu_length, credits, interval, repetition_period);
681     }
682
683     /* TODO: Spare extension may follow */
684 }
685
686
687 /* Dissect the control part of a common channel message */
688 void dissect_common_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
689                             int offset, struct _fp_info *p_fp_info)
690 {
691     /* Common control frame type */
692     guint8 control_frame_type = tvb_get_guint8(tvb, offset);
693     proto_tree_add_item(tree, hf_fp_common_control_frame_type, tvb, offset, 1, FALSE);
694     offset++;
695
696     if (check_col(pinfo->cinfo, COL_INFO))
697     {
698         col_append_str(pinfo->cinfo, COL_INFO,
699                        val_to_str(control_frame_type, common_control_frame_type_vals, "Unknown"));
700     }
701
702     /* Frame-type specific dissection */
703     switch (control_frame_type)
704     {
705         case COMMON_OUTER_LOOP_POWER_CONTROL:
706             break;
707         case COMMON_TIMING_ADJUSTMENT:
708             dissect_common_timing_adjustment(pinfo, tree, tvb, offset, p_fp_info);
709             break;
710         case COMMON_DL_SYNCHRONISATION:
711             dissect_common_dl_syncronisation(pinfo, tree, tvb, offset, p_fp_info);
712             break;
713         case COMMON_UL_SYNCHRONISATION:
714             dissect_common_ul_syncronisation(pinfo, tree, tvb, offset, p_fp_info);
715             break;
716         case COMMON_DL_NODE_SYNCHRONISATION:
717             dissect_common_dl_node_synchronisation(pinfo, tree, tvb, offset);
718             break;
719         case COMMON_UL_NODE_SYNCHRONISATION:
720             dissect_common_ul_node_synchronisation(pinfo, tree, tvb, offset);
721             break;
722         case COMMON_DYNAMIC_PUSCH_ASSIGNMENT:
723             /* TODO: */
724             break;
725         case COMMON_TIMING_ADVANCE:
726             dissect_common_timing_advance(tree, tvb, offset);
727             break;
728         case COMMON_HS_DSCH_Capacity_Request:
729             dissect_hsdpa_capacity_request(pinfo, tree, tvb, offset);
730             break;
731         case COMMON_HS_DSCH_Capacity_Allocation:
732             dissect_hsdpa_capacity_allocation(pinfo, tree, tvb, offset);
733             break;
734
735         default:
736             break;
737     }
738 }
739
740
741
742 /**************************/
743 /* Dissect a RACH channel */
744 void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
745                                int offset, struct _fp_info *p_fp_info)
746 {
747     gboolean is_control_frame;
748
749     /* Header CRC */
750     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
751
752     /* Frame Type */
753     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
754     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
755     offset++;
756
757     if (check_col(pinfo->cinfo, COL_INFO))
758     {
759         col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
760     }
761
762     if (is_control_frame)
763     {
764         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
765     }
766     else
767     {
768         int num_tbs = 0;
769         guint8 cfn;
770
771         /* DATA */
772
773         /* CFN */
774         cfn = tvb_get_guint8(tvb, offset);
775         proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
776         offset++;
777
778         if (check_col(pinfo->cinfo, COL_INFO))
779         {
780             col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
781         }
782
783         /* TFI */
784         proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, FALSE);
785         offset++;
786
787         if (p_fp_info->channel == CHANNEL_RACH_FDD)
788         {
789             /* Propagation delay */
790             proto_tree_add_item(tree, hf_fp_propagation_delay, tvb, offset, 1, FALSE);
791             offset++;
792         }
793
794         if (p_fp_info->channel == CHANNEL_RACH_TDD)
795         {
796             /* RX Timing Deviation */
797         }
798
799         if (p_fp_info->channel == CHANNEL_RACH_TDD_128)
800         {
801             /* Received SYNC UL Timing Deviation */
802             proto_tree_add_item(tree, hf_fp_received_sync_ul_timing_deviation, tvb, offset, 1, FALSE);
803             offset++;
804         }
805
806         /* TB data */
807         offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
808
809         /* CRCIs */
810         offset = dissect_crci_bits(tvb, pinfo, tree, num_tbs, offset);
811
812         /* Payload CRC */
813         proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, 2, FALSE);
814         offset += 2;
815     }
816 }
817
818
819 /**************************/
820 /* Dissect a FACH channel */
821 void dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
822                                int offset, struct _fp_info *p_fp_info)
823 {
824     gboolean is_control_frame;
825
826     /* Header CRC */
827     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
828
829     /* Frame Type */
830     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
831     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
832     offset++;
833
834     if (check_col(pinfo->cinfo, COL_INFO))
835     {
836         col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
837     }
838
839     if (is_control_frame)
840     {
841         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
842     }
843     else
844     {
845         int num_tbs = 0;
846         guint8 cfn;
847
848         /* DATA */
849
850         /* CFN */
851         cfn = tvb_get_guint8(tvb, offset);
852         proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
853         offset++;
854
855         if (check_col(pinfo->cinfo, COL_INFO))
856         {
857             col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
858         }
859
860         /* TFI */
861         proto_tree_add_item(tree, hf_fp_fach_tfi, tvb, offset, 1, FALSE);
862         offset++;
863
864         /* Transmit power level. TODO: units are 0.1dB */
865         proto_tree_add_item(tree, hf_fp_transmit_power_level, tvb, offset, 1, FALSE);
866         offset++;
867
868         /* TB data */
869         offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
870
871         /* Payload CRC */
872         proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, 2, FALSE);
873         offset += 2;
874     }
875 }
876
877
878 /**************************/
879 /* Dissect a DSCH channel */
880 void dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
881                                int offset, struct _fp_info *p_fp_info)
882 {
883     gboolean is_control_frame;
884
885     /* Header CRC */
886     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
887
888     /* Frame Type */
889     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
890     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
891     offset++;
892
893     if (check_col(pinfo->cinfo, COL_INFO))
894     {
895         col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
896     }
897
898     if (is_control_frame)
899     {
900         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
901     }
902     else
903     {
904         int num_tbs = 0;
905         guint8 cfn;
906
907         /* DATA */
908
909         /* CFN */
910         cfn = tvb_get_guint8(tvb, offset);
911         proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
912         offset++;
913
914         if (check_col(pinfo->cinfo, COL_INFO))
915         {
916             col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
917         }
918
919         /* TFI */
920         proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, FALSE);
921         offset++;
922
923         /* PDSCH Set Id */
924         proto_tree_add_item(tree, hf_fp_pdsch_set_id, tvb, offset, 1, FALSE);
925         offset++;
926
927         /* Transmit power level. TODO: units are 0.1dB */
928         proto_tree_add_item(tree, hf_fp_transmit_power_level, tvb, offset, 1, FALSE);
929         offset++;
930
931         /* TB data */
932         offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
933
934         /* Payload CRC */
935         proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, 2, FALSE);
936         offset += 2;
937     }
938 }
939
940
941 /**************************/
942 /* Dissect a USCH channel */
943 void dissect_usch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
944                                int offset, struct _fp_info *p_fp_info)
945 {
946     gboolean is_control_frame;
947
948     /* Header CRC */
949     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
950
951     /* Frame Type */
952     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
953     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
954     offset++;
955
956     if (check_col(pinfo->cinfo, COL_INFO))
957     {
958         col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
959     }
960
961     if (is_control_frame)
962     {
963         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
964     }
965     else
966     {
967         int num_tbs = 0;
968         guint cfn;
969
970         /* DATA */
971
972         /* CFN */
973         cfn = tvb_get_guint8(tvb, offset);
974         proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
975         offset++;
976
977         if (check_col(pinfo->cinfo, COL_INFO))
978         {
979             col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
980         }
981
982         /* TFI */
983         proto_tree_add_item(tree, hf_fp_usch_tfi, tvb, offset, 1, FALSE);
984         offset++;
985
986         /* Rx Timing Deviation */
987         proto_tree_add_item(tree, hf_fp_rx_timing_deviation, tvb, offset, 1, FALSE);
988         offset++;
989
990         /* TB data */
991         offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
992
993         /* QE */
994         proto_tree_add_item(tree, hf_fp_quality_estimate, tvb, offset, 1, FALSE);
995         offset++;
996
997         /* CRCIs */
998         offset = dissect_crci_bits(tvb, pinfo, tree, num_tbs, offset);
999
1000         /* Payload CRC */
1001         proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, 2, FALSE);
1002         offset += 2;
1003     }
1004 }
1005
1006
1007
1008 /**************************/
1009 /* Dissect a PCH channel  */
1010 void dissect_pch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1011                               int offset, struct _fp_info *p_fp_info)
1012 {
1013     gboolean is_control_frame;
1014     guint16  pch_cfn;
1015     gboolean paging_indication;
1016
1017     /* Header CRC */
1018     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1019
1020     /* Frame Type */
1021     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1022     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1023     offset++;
1024
1025     if (check_col(pinfo->cinfo, COL_INFO))
1026     {
1027         col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1028     }
1029
1030     if (is_control_frame)
1031     {
1032         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1033     }
1034     else
1035     {
1036         int num_tbs = 0;
1037
1038         /* DATA */
1039
1040         /* 12-bit CFN value */
1041         proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, FALSE);
1042         pch_cfn = (tvb_get_ntohs(tvb, offset) & 0xfff0) >> 4;
1043         offset++;
1044
1045         if (check_col(pinfo->cinfo, COL_INFO))
1046         {
1047             col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%04u ", pch_cfn);
1048         }
1049
1050         /* Paging indication */
1051         proto_tree_add_item(tree, hf_fp_pch_pi, tvb, offset, 1, FALSE);
1052         paging_indication = tvb_get_guint8(tvb, offset) & 0x01;
1053         offset++;
1054
1055         /* 5-bit TFI */
1056         proto_tree_add_item(tree, hf_fp_pch_tfi, tvb, offset, 1, FALSE);
1057         offset++;
1058
1059         /* Optional paging indications */
1060         if (paging_indication)
1061         {
1062             proto_item *ti;
1063             ti = proto_tree_add_item(tree, hf_fp_paging_indication_bitmap, tvb,
1064                                      offset,
1065                                      (p_fp_info->paging_indications+7) / 8,
1066                                      FALSE);
1067             proto_item_append_text(ti, " (%u bits)", p_fp_info->paging_indications);
1068         }
1069
1070         /* TB data */
1071         offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
1072
1073         /* Payload CRC */
1074         proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, 2, FALSE);
1075         offset += 2;
1076     }
1077 }
1078
1079
1080 /********************************/
1081 /* Dissect an IUR DSCH channel  */
1082 void dissect_iur_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1083                                    int offset, struct _fp_info *p_fp_info _U_)
1084 {
1085     gboolean is_control_frame;
1086
1087     /* Header CRC */
1088     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1089
1090     /* Frame Type */
1091     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1092     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1093     offset++;
1094
1095     if (check_col(pinfo->cinfo, COL_INFO))
1096     {
1097         col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1098     }
1099
1100
1101     if (is_control_frame)
1102     {
1103         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1104     }
1105     else
1106     {
1107         /* TODO: DATA */
1108     }
1109 }
1110
1111
1112
1113
1114 /************************/
1115 /* DCH control messages */
1116
1117 void dissect_dch_timing_adjustment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
1118 {
1119     guint8 control_cfn;
1120     gint16 toa;
1121
1122     /* CFN control */
1123     control_cfn = tvb_get_guint8(tvb, offset);
1124     proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
1125     offset++;
1126
1127     /* ToA */
1128     toa = tvb_get_ntohs(tvb, offset);
1129     proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, FALSE);
1130     offset += 2;
1131
1132     if (check_col(pinfo->cinfo, COL_INFO))
1133     {
1134         col_append_fstr(pinfo->cinfo, COL_INFO,
1135                         " CFN = %u, ToA = %d", control_cfn, toa);
1136     }
1137 }
1138
1139 void dissect_dch_rx_timing_deviation(proto_tree *tree, tvbuff_t *tvb, int offset)
1140 {
1141     /* CFN control */
1142     proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
1143     offset++;
1144
1145     /* Rx Timing Deviation */
1146     proto_tree_add_item(tree, hf_fp_dch_rx_timing_deviation, tvb, offset, 1, FALSE);
1147     offset++;
1148 }
1149
1150 void dissect_dch_dl_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
1151 {
1152     /* CFN control */
1153     guint cfn = tvb_get_guint8(tvb, offset);
1154     proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
1155     offset++;
1156
1157     if (check_col(pinfo->cinfo, COL_INFO))
1158     {
1159         col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u", cfn);
1160     }
1161 }
1162
1163 void dissect_dch_ul_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
1164 {
1165     guint8 cfn;
1166     gint16 toa;
1167
1168     /* CFN control */
1169     cfn = tvb_get_guint8(tvb, offset);
1170     proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
1171     offset++;
1172
1173     /* ToA */
1174     toa = tvb_get_ntohs(tvb, offset);
1175     proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, FALSE);
1176     offset += 2;
1177
1178     if (check_col(pinfo->cinfo, COL_INFO))
1179     {
1180         col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, ToA = %d",
1181                         cfn, toa);
1182     }
1183 }
1184
1185 void dissect_dch_outer_loop_power_control(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
1186 {
1187     /* SIR target */
1188     float target = -8.2 + (0.1*(float)tvb_get_guint8(tvb, offset));
1189     proto_tree_add_float(tree, hf_fp_ul_sir_target, tvb, offset, 1, target);
1190
1191     if (check_col(pinfo->cinfo, COL_INFO))
1192     {
1193         col_append_fstr(pinfo->cinfo, COL_INFO, "SIR Target = %f", target);
1194     }
1195 }
1196
1197 void dissect_dch_dl_node_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
1198 {
1199     dissect_common_dl_node_synchronisation(pinfo, tree, tvb, offset);
1200 }
1201
1202 void dissect_dch_ul_node_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
1203 {
1204     dissect_common_ul_node_synchronisation(pinfo, tree, tvb, offset);
1205 }
1206
1207
1208
1209 /*******************************/
1210 /* Dissect a DCH channel       */
1211 void dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1212                               int offset, struct _fp_info *p_fp_info)
1213 {
1214     gboolean is_control_frame;
1215     guint8   control_frame_type;
1216     guint8   cfn;
1217
1218     /* Header CRC */
1219     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1220
1221     /* Frame Type */
1222     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1223     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1224     offset++;
1225
1226     if (check_col(pinfo->cinfo, COL_INFO))
1227     {
1228         col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1229     }
1230
1231     if (is_control_frame)
1232     {
1233         /* DCH control frame */
1234
1235         /* Control frame type */
1236         control_frame_type = tvb_get_guint8(tvb, offset);
1237         proto_tree_add_item(tree, hf_fp_dch_control_frame_type, tvb, offset, 1, FALSE);
1238         offset++;
1239
1240         if (check_col(pinfo->cinfo, COL_INFO))
1241         {
1242             col_append_str(pinfo->cinfo, COL_INFO,
1243                            val_to_str(control_frame_type,
1244                                       dch_control_frame_type_vals, "Unknown"));
1245         }
1246
1247         switch (control_frame_type)
1248         {
1249             case DCH_TIMING_ADJUSTMENT:
1250                 dissect_dch_timing_adjustment(tree, pinfo, tvb, offset);
1251                 break;
1252             case DCH_RX_TIMING_DEVIATION:
1253                 dissect_dch_rx_timing_deviation(tree, tvb, offset);
1254                 break;
1255             case DCH_DL_SYNCHRONISATION:
1256                 dissect_dch_dl_synchronisation(tree, pinfo, tvb, offset);
1257                 break;
1258             case DCH_UL_SYNCHRONISATION:
1259                 dissect_dch_ul_synchronisation(tree, pinfo, tvb, offset);
1260                 break;
1261             case DCH_OUTER_LOOP_POWER_CONTROL:
1262                 dissect_dch_outer_loop_power_control(tree, pinfo, tvb, offset);
1263                 break;
1264             case DCH_DL_NODE_SYNCHRONISATION:
1265                 dissect_dch_dl_node_synchronisation(tree, pinfo, tvb, offset);
1266                 break;
1267             case DCH_UL_NODE_SYNCHRONISATION:
1268                 dissect_dch_ul_node_synchronisation(tree, pinfo, tvb, offset);
1269                 break;
1270             case DCH_RADIO_INTERFACE_PARAMETER_UPDATE:
1271             case DCH_TIMING_ADVANCE:
1272             case DCH_TNL_CONGESTION_INDICATION:
1273                 /* TODO: */
1274                 break;
1275         }
1276     }
1277     else
1278     {
1279         /************************/
1280         /* DCH data here        */
1281         int chan;
1282         int num_tbs = 0;
1283
1284         /* CFN */
1285         proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
1286         cfn = tvb_get_guint8(tvb, offset);
1287         offset++;
1288
1289         if (check_col(pinfo->cinfo, COL_INFO))
1290         {
1291             col_append_fstr(pinfo->cinfo, COL_INFO, "CFN=%03u ", cfn);
1292         }
1293
1294         /* One TFI for each channel */
1295         for (chan=0; chan < p_fp_info->num_chans; chan++)
1296         {
1297             proto_tree_add_item(tree, hf_fp_tfi, tvb, offset, 1, FALSE);
1298             offset++;
1299         }
1300
1301         /* Dissect TB data */
1302         offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
1303
1304         /* QE (uplink only) */
1305         if (p_fp_info->is_uplink)
1306         {
1307             proto_tree_add_item(tree, hf_fp_quality_estimate, tvb, offset, 1, FALSE);
1308             offset++;
1309         }
1310
1311         /* CRCI bits (uplink only) */
1312         if (p_fp_info->is_uplink)
1313         {
1314             offset = dissect_crci_bits(tvb, pinfo, tree, num_tbs, offset);
1315         }
1316
1317         /* Payload CRC (optional) */
1318         if (p_fp_info->dch_crc_present)
1319         {
1320             proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, 2, FALSE);
1321         }
1322     }
1323 }
1324
1325
1326
1327 /**********************************/
1328 /* Dissect an E-DCH channel       */
1329 void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1330                                 int offset, struct _fp_info *p_fp_info)
1331 {
1332     gboolean is_control_frame;
1333     guint8   number_of_subframes;
1334     guint8   cfn;
1335     int      n;
1336     struct   subframe_info subframes[8];
1337
1338     /* Header CRC */
1339     proto_tree_add_item(tree, hf_fp_edch_header_crc, tvb, offset, 2, FALSE);
1340
1341     /* Frame Type */
1342     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1343     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1344     offset++;
1345
1346     if (check_col(pinfo->cinfo, COL_INFO))
1347     {
1348         col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1349     }
1350
1351     if (is_control_frame)
1352     {
1353         /* TODO: will this be seen? */
1354     }
1355     else
1356     {
1357         /********************************/
1358         /* E-DCH data here        */
1359
1360         guint  bit_offset = 0;
1361         guint  total_bits = 0;
1362
1363         /* FSN */
1364         proto_tree_add_item(tree, hf_fp_edch_fsn, tvb, offset, 1, FALSE);
1365         offset++;
1366
1367         /* Number of subframes (was 3, now 4 bits) */
1368         number_of_subframes = (tvb_get_guint8(tvb, offset) & 0x0f);
1369         proto_tree_add_item(tree, hf_fp_edch_number_of_subframes, tvb, offset, 1, FALSE);
1370         offset++;
1371
1372         /* CFN */
1373         cfn = tvb_get_guint8(tvb, offset);
1374         proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
1375         offset++;
1376
1377         /* EDCH subframe header list */
1378         for (n=0; n < number_of_subframes; n++)
1379         {
1380             int i;
1381             proto_item *subframe_header_ti;
1382             proto_tree *subframe_header_tree;
1383
1384             /* Add subframe header subtree */
1385             subframe_header_ti = proto_tree_add_string_format(tree, hf_fp_edch_subframe_header, tvb, offset, 0,
1386                                                               "", "Subframe");
1387             subframe_header_tree = proto_item_add_subtree(subframe_header_ti, ett_fp_edch_subframe_header);
1388
1389             /* Number of HARQ Retransmissions */
1390             proto_tree_add_item(subframe_header_tree, hf_fp_edch_harq_retransmissions, tvb,
1391                                 offset, 1, FALSE);
1392
1393             /* Subframe number */
1394             subframes[n].subframe_number = (tvb_get_guint8(tvb, offset) & 0x07);
1395             proto_tree_add_item(subframe_header_tree, hf_fp_edch_subframe_number, tvb,
1396                                 offset, 1, FALSE);
1397             offset++;
1398
1399             /* Number of MAC-es PDUs */
1400             subframes[n].number_of_mac_es_pdus = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
1401             proto_tree_add_item(subframe_header_tree, hf_fp_edch_number_of_mac_es_pdus,
1402                                 tvb, offset, 1, FALSE);
1403             bit_offset = 4;
1404
1405             proto_item_append_text(subframe_header_ti, " %u header (%u MAC-es PDUs)",
1406                                    subframes[n].subframe_number,
1407                                    subframes[n].number_of_mac_es_pdus);
1408
1409             /* Details of each MAC-es PDU */
1410             for (i=0; i < subframes[n].number_of_mac_es_pdus; i++)
1411             {
1412                 guint8 ddi;
1413                 int    ddi_offset;
1414                 guint8 n_pdus;
1415                 int    n_pdus_offset;
1416
1417                 /* DDI (6 bits) */
1418                 ddi_offset = offset + (bit_offset / 8);
1419
1420                 switch (bit_offset%8)
1421                 {
1422                     case 0:
1423                         ddi = (tvb_get_guint8(tvb, ddi_offset) >> 2);
1424                         break;
1425                     case 2:
1426                         ddi = (tvb_get_guint8(tvb, ddi_offset) & 0x3f);
1427                         break;
1428                     case 4:
1429                         ddi = (tvb_get_ntohs(tvb, ddi_offset) >> 6) & 0x003f;
1430                         break;
1431                     case 6:
1432                         ddi = (tvb_get_ntohs(tvb, ddi_offset) >> 4) & 0x003f;
1433                         break;
1434                     default:
1435                         /* Can't get here, but avoid warning */
1436                         return;
1437                 }
1438
1439                 proto_tree_add_uint(subframe_header_tree, hf_fp_edch_ddi, tvb, ddi_offset,
1440                                     ((bit_offset%8) <= 2) ? 1 : 2, ddi);
1441
1442                 subframes[n].ddi[i] = ddi;
1443                 bit_offset += 6;
1444
1445                 /* Number of MAC-d PDUs (6 bits) */
1446                 n_pdus_offset = offset + (bit_offset / 8);
1447                 switch (bit_offset%8)
1448                 {
1449                     case 0:
1450                         n_pdus = (tvb_get_guint8(tvb, n_pdus_offset) >> 2);
1451                         break;
1452                     case 2:
1453                         n_pdus = (tvb_get_guint8(tvb, n_pdus_offset) & 0x3f);
1454                         break;
1455                     case 4:
1456                         n_pdus = (tvb_get_ntohs(tvb, n_pdus_offset) >> 6) & 0x003f;
1457                         break;
1458                     case 6:
1459                         n_pdus = (tvb_get_ntohs(tvb, n_pdus_offset) >> 4) & 0x003f;
1460                         break;
1461                     default:
1462                         /* Can't get here, but avoid warning */
1463                         return;
1464                 }
1465                 proto_tree_add_uint(subframe_header_tree, hf_fp_edch_number_of_mac_d_pdus, tvb, n_pdus_offset,
1466                                     ((bit_offset%8) <= 2) ? 1 : 2, n_pdus);
1467
1468                 subframes[n].number_of_mac_d_pdus[i] = n_pdus;
1469                 bit_offset += 6;
1470             }
1471
1472             /* Tree should cover entire subframe header */
1473             proto_item_set_len(subframe_header_ti, bit_offset/8);
1474
1475             offset += ((bit_offset+7)/8);
1476         }
1477
1478         /* EDCH subframes */
1479         bit_offset = 0;
1480         for (n=0; n < number_of_subframes; n++)
1481         {
1482             int i;
1483             proto_item *subframe_ti;
1484             proto_tree *subframe_tree;
1485             guint bits_in_subframe = 0;
1486             guint mac_d_pdus_in_subframe = 0;
1487
1488             bit_offset = 0;
1489
1490             /* Add subframe subtree */
1491             subframe_ti = proto_tree_add_string_format(tree, hf_fp_edch_subframe, tvb, offset, 0,
1492                                                        "", "Subframe %u data", subframes[n].subframe_number);
1493             subframe_tree = proto_item_add_subtree(subframe_ti, ett_fp_edch_subframe);
1494
1495             for (i=0; i < subframes[n].number_of_mac_es_pdus; i++)
1496             {
1497                 int m;
1498                 guint8 size = 0;
1499                 guint  send_size;
1500                 proto_item *ti;
1501
1502                 /* Look up mac-d pdu size for this ddi */
1503                 for (m=0; m < p_fp_info->no_ddi_entries; m++)
1504                 {
1505                     if (subframes[n].ddi[i] == p_fp_info->edch_ddi[m])
1506                     {
1507                         size = p_fp_info->edch_macd_pdu_size[m];
1508                         break;
1509                     }
1510                 }
1511
1512                 if (m == p_fp_info->no_ddi_entries)
1513                 {
1514                     /* Not found.  Oops */
1515                     return;
1516                 }
1517
1518                 /* Send MAC-dd PDUs together as one MAC-es PDU */
1519                 send_size = size * subframes[n].number_of_mac_d_pdus[i];
1520
1521                 /* 2 bits spare */
1522                 proto_tree_add_item(subframe_tree, hf_fp_edch_pdu_padding, tvb,
1523                                     offset + (bit_offset/8),
1524                                     1, FALSE);
1525                 bit_offset += 2;
1526
1527                 /* TSN */
1528                 proto_tree_add_item(subframe_tree, hf_fp_edch_tsn, tvb,
1529                                     offset + (bit_offset/8),
1530                                     1, FALSE);
1531                 bit_offset += 6;
1532
1533                 /* PDU */
1534                 ti = proto_tree_add_item(subframe_tree, hf_fp_edch_mac_es_pdu, tvb,
1535                                          offset + (bit_offset/8),
1536                                          ((bit_offset % 8) + send_size + 7) / 8,
1537                                          FALSE);
1538                 proto_item_append_text(ti, " (%u * %u = %u bits, subframe %d)",
1539                                        size, subframes[n].number_of_mac_d_pdus[i],
1540                                        send_size, n);
1541                 bits_in_subframe += send_size;
1542                 mac_d_pdus_in_subframe += subframes[n].number_of_mac_d_pdus[i];
1543
1544                 bit_offset += send_size;
1545
1546                 /* Pad out to next byte */
1547                 if (bit_offset % 8)
1548                 {
1549                     bit_offset += (8 - (bit_offset % 8));
1550                 }
1551             }
1552
1553             /* Tree should cover entire subframe */
1554             proto_item_set_len(subframe_ti, bit_offset/8);
1555
1556             /* Append summary info to subframe label */
1557             proto_item_append_text(subframe_ti, " (%u bits in %u MAC-d PDUs)",
1558                                    bits_in_subframe, mac_d_pdus_in_subframe);
1559             total_bits += bits_in_subframe;
1560
1561             offset += (bit_offset/8);
1562         }
1563
1564         /* Report number of subframes in info column */
1565         if (check_col(pinfo->cinfo, COL_INFO))
1566         {
1567             col_append_fstr(pinfo->cinfo, COL_INFO,
1568                             " CFN = %03u   (%u bits in %u subframes)",
1569                             cfn, total_bits, number_of_subframes);
1570         }
1571
1572         /* Payload CRC (optional) */
1573         /* TODO: is this test correct...? */
1574         if (p_fp_info->dch_crc_present)
1575         {
1576             proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, 2, FALSE);
1577         }
1578     }
1579 }
1580
1581
1582 /***********************************/
1583 /* Dissect an HSDSCH channel       */
1584 void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1585                                  int offset, struct _fp_info *p_fp_info)
1586 {
1587     gboolean is_control_frame;
1588
1589     /* Header CRC */
1590     proto_tree_add_item(tree, hf_fp_header_crc, tvb, offset, 1, FALSE);
1591
1592     /* Frame Type */
1593     is_control_frame = tvb_get_guint8(tvb, offset) & 0x01;
1594     proto_tree_add_item(tree, hf_fp_ft, tvb, offset, 1, FALSE);
1595     offset++;
1596
1597     if (check_col(pinfo->cinfo, COL_INFO))
1598     {
1599         col_append_str(pinfo->cinfo, COL_INFO, is_control_frame ? " [Control] " : " [Data] ");
1600     }
1601
1602     if (is_control_frame)
1603     {
1604         dissect_common_control(tvb, pinfo, tree, offset, p_fp_info);
1605     }
1606     else
1607     {
1608         guint8 number_of_pdus;
1609         guint16 pdu_length;
1610
1611         /********************************/
1612         /* HS-DCH data here             */
1613
1614         /* CmCH-PI */
1615         proto_tree_add_item(tree, hf_fp_cmch_pi, tvb, offset, 1, FALSE);
1616         offset++;
1617
1618         /* MAC-d PDU Length (13 bits) */
1619         pdu_length = (tvb_get_ntohs(tvb, offset) >> 3);
1620         proto_tree_add_item(tree, hf_fp_mac_d_pdu_len, tvb, offset, 2, FALSE);
1621         offset += 2;
1622
1623         /* Num of PDU */
1624         number_of_pdus = tvb_get_guint8(tvb, offset);
1625         proto_tree_add_item(tree, hf_fp_num_of_pdu, tvb, offset, 1, FALSE);
1626         offset++;
1627
1628         /* User buffer size */
1629         proto_tree_add_item(tree, hf_fp_user_buffer_size, tvb, offset, 2, FALSE);
1630         offset += 2;
1631
1632         /* MAC-d PDUs */
1633         offset = dissect_macd_pdu_data(tvb, pinfo, tree, offset, pdu_length,
1634                                        number_of_pdus);
1635
1636         /* Extra R6 stuff */
1637         if (p_fp_info->release == 6)
1638         {
1639             int n;
1640             guint8 flags;
1641             guint8 flag_bytes = 0;
1642
1643             /* New IE flags */
1644             do
1645             {
1646                 /* Read next byte */
1647                 flags = tvb_get_guint8(tvb, offset);
1648                 flag_bytes++;
1649
1650                 /* Dissect individual bits */
1651                 for (n=0; n < 8; n++)
1652                 {
1653                     proto_tree_add_item(tree, hf_fp_hsdsch_new_ie_flags[n], tvb, offset, 1, FALSE);
1654                 }
1655                 offset++;
1656
1657                 /* Last bit set will indicate another flags byte follows... */
1658             } while (0); /*((flags & 0x01) && (flag_bytes < 31));*/
1659
1660             if (1) /*(flags & 0x8) */
1661             {
1662                 /* DRT is shown as mandatory in the diagram (3GPP TS 25.435 V6.3.0),
1663                    but the description below it states that
1664                    it should depend upon the first bit.  The detailed description of
1665                    New IE flags doesn't agree, so treat as mandatory for now... */
1666                 proto_tree_add_item(tree, hf_fp_hsdsch_drt, tvb, offset, 2, FALSE);
1667                 offset += 2;
1668             }
1669         }
1670
1671         /* TODO: may be spare extension to skip */
1672
1673         /* Payload CRC */
1674         proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, 2, FALSE);
1675     }
1676 }
1677
1678
1679
1680
1681 /*****************************/
1682 /* Main dissection function. */
1683 void dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1684 {
1685     proto_tree       *fp_tree;
1686     proto_item       *ti;
1687     gint             offset = 0;
1688     struct _fp_info  *p_fp_info;
1689
1690     /* Append this protocol name rather than replace. */
1691     if (check_col(pinfo->cinfo, COL_PROTOCOL))
1692         col_set_str(pinfo->cinfo, COL_PROTOCOL, "FP");
1693
1694     /* Create fp tree. */
1695     ti = proto_tree_add_item(tree, proto_fp, tvb, offset, -1, FALSE);
1696     fp_tree = proto_item_add_subtree(ti, ett_fp);
1697
1698     /* Look for packet info! */
1699     p_fp_info = p_get_proto_data(pinfo->fd, proto_fp);
1700
1701     /* Can't dissect anything without it... */
1702     if (p_fp_info == NULL)
1703     {
1704         return;
1705     }
1706
1707     /* Show channel type in info column, tree */
1708     if (check_col(pinfo->cinfo, COL_INFO))
1709     {
1710         col_set_str(pinfo->cinfo, COL_INFO,
1711                     val_to_str(p_fp_info->channel,
1712                                channel_type_vals,
1713                                "Unknown channel type"));
1714     }
1715     proto_item_append_text(ti, " (%s)",
1716                            val_to_str(p_fp_info->channel,
1717                                       channel_type_vals,
1718                                       "Unknown channel type"));
1719
1720     /* Add channel type as a generated field */
1721     ti = proto_tree_add_uint(fp_tree, hf_fp_channel_type, tvb, 0, 0, p_fp_info->channel);
1722     PROTO_ITEM_SET_GENERATED(ti);
1723
1724     /* Add link direction as a generated field */
1725     ti = proto_tree_add_uint(fp_tree, hf_fp_direction, tvb, 0, 0, p_fp_info->is_uplink);
1726     PROTO_ITEM_SET_GENERATED(ti);
1727
1728
1729     /*************************************/
1730     /* Dissect according to channel type */
1731     switch (p_fp_info->channel)
1732     {
1733         case CHANNEL_RACH_TDD:
1734         case CHANNEL_RACH_TDD_128:
1735         case CHANNEL_RACH_FDD:
1736             dissect_rach_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
1737             break;
1738         case CHANNEL_DCH:
1739             dissect_dch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
1740             break;
1741         case CHANNEL_FACH_FDD:
1742         case CHANNEL_FACH_TDD:
1743             dissect_fach_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
1744             break;
1745         case CHANNEL_DSCH_FDD:
1746         case CHANNEL_DSCH_TDD:
1747             dissect_dsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
1748             break;
1749         case CHANNEL_USCH_TDD_128:
1750         case CHANNEL_USCH_TDD_384:
1751             dissect_usch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
1752             break;
1753         case CHANNEL_PCH:
1754             dissect_pch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
1755             break;
1756         case CHANNEL_CPCH:
1757             /* TODO */
1758             break;
1759         case CHANNEL_BCH:
1760             /* TODO */
1761             break;
1762         case CHANNEL_HSDSCH:
1763             dissect_hsdsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
1764             break;
1765         case CHANNEL_IUR_CPCHF:
1766             break;
1767         case CHANNEL_IUR_FACH:
1768             break;
1769         case CHANNEL_IUR_DSCH:
1770             dissect_iur_dsch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
1771             break;
1772         case CHANNEL_EDCH:
1773             dissect_e_dch_channel_info(tvb, pinfo, fp_tree, offset, p_fp_info);
1774             break;
1775
1776         default:
1777             break;
1778     }
1779 }
1780
1781 void proto_register_fp(void)
1782 {
1783     static hf_register_info hf[] =
1784     {
1785         { &hf_fp_channel_type,
1786             { "Channel Type",
1787               "fp.channel-type", FT_UINT8, BASE_HEX, VALS(channel_type_vals), 0x0,
1788               "Channel Type", HFILL
1789             }
1790         },
1791         { &hf_fp_direction,
1792             { "Direction",
1793               "fp.direction", FT_UINT8, BASE_HEX, VALS(direction_vals), 0x0,
1794               "Link direction", HFILL
1795             }
1796         },
1797         { &hf_fp_header_crc,
1798             { "Header CRC",
1799               "fp.header-crc", FT_UINT8, BASE_HEX, NULL, 0xfe,
1800               "Header CRC", HFILL
1801             }
1802         },
1803         { &hf_fp_ft,
1804             { "Frame Type",
1805               "fp.ft", FT_UINT8, BASE_HEX, VALS(data_control_vals), 0x01,
1806               "Frame Type", HFILL
1807             }
1808         },
1809         { &hf_fp_cfn,
1810             { "CFN",
1811               "fp.cfn", FT_UINT8, BASE_DEC, NULL, 0x0,
1812               "Connection Frame Number", HFILL
1813             }
1814         },
1815         { &hf_fp_pch_cfn,
1816             { "CFN (PCH)",
1817               "fp.pch.cfn", FT_UINT16, BASE_DEC, NULL, 0xfff0,
1818               "PCH Connection Frame Number", HFILL
1819             }
1820         },
1821         { &hf_fp_pch_toa,
1822             { "ToA (PCH)",
1823               "fp.pch.toa", FT_INT24, BASE_DEC, NULL, 0x0,
1824               "PCH Time of Arrival", HFILL
1825             }
1826         },
1827         { &hf_fp_cfn_control,
1828             { "CFN control",
1829               "fp.cfn-control", FT_UINT8, BASE_DEC, NULL, 0x0,
1830               "Connection Frame Number Control", HFILL
1831             }
1832         },
1833         { &hf_fp_toa,
1834             { "ToA",
1835               "fp.cfn-control", FT_INT16, BASE_DEC, NULL, 0x0,
1836               "Connection Frame Number Control", HFILL
1837             }
1838         },
1839         { &hf_fp_tb,
1840             { "TB",
1841               "fp.tb", FT_NONE, BASE_NONE, NULL, 0x0,
1842               "TB", HFILL
1843             }
1844         },
1845         { &hf_fp_tfi,
1846             { "TFI",
1847               "fp.tfi", FT_UINT8, BASE_DEC, NULL, 0x0,
1848               "Transport Format Indicator", HFILL
1849             }
1850         },
1851         { &hf_fp_usch_tfi,
1852             { "TFI",
1853               "fp.usch.tfi", FT_UINT8, BASE_DEC, NULL, 0x1f,
1854               "USCH Transport Format Indicator", HFILL
1855             }
1856         },
1857         { &hf_fp_propagation_delay,
1858             { "Propagation Delay",
1859               "fp.propagation-delay", FT_UINT8, BASE_DEC, NULL, 0x0,
1860               "Propagation Delay", HFILL
1861             }
1862         },
1863         { &hf_fp_dch_control_frame_type,
1864             { "Control Frame Type",
1865               "fp.dch.control.frame-type", FT_UINT8, BASE_HEX, VALS(dch_control_frame_type_vals), 0x0,
1866               "DCH Control Frame Type", HFILL
1867             }
1868         },
1869         { &hf_fp_dch_rx_timing_deviation,
1870             { "Rx Timing Deviation",
1871               "fp.dch.control.rx-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
1872               "DCH Rx Timing Deviation", HFILL
1873             }
1874         },
1875         { &hf_fp_quality_estimate,
1876             { "Quality Estimate",
1877               "fp.dch.quality-estimate", FT_UINT8, BASE_DEC, 0, 0x0,
1878               "Quality Estimate", HFILL
1879             }
1880         },
1881         { &hf_fp_payload_crc,
1882             { "Payload CRC",
1883               "fp.payload-crc", FT_UINT16, BASE_HEX, 0, 0x0,
1884               "Payload CRC", HFILL
1885             }
1886         },
1887         { &hf_fp_common_control_frame_type,
1888             { "Control Frame Type",
1889               "fp.common.control.frame-type", FT_UINT8, BASE_HEX, VALS(common_control_frame_type_vals), 0x0,
1890               "Common Control Frame Type", HFILL
1891             }
1892         },
1893         { &hf_fp_crci[0],
1894             { "CRCI",
1895               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x80,
1896               "CRC correctness indicator", HFILL
1897             }
1898         },
1899         { &hf_fp_crci[1],
1900             { "CRCI",
1901               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x40,
1902               "CRC correctness indicator", HFILL
1903             }
1904         },
1905         { &hf_fp_crci[2],
1906             { "CRCI",
1907               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x20,
1908               "CRC correctness indicator", HFILL
1909             }
1910         },
1911         { &hf_fp_crci[3],
1912             { "CRCI",
1913               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x10,
1914               "CRC correctness indicator", HFILL
1915             }
1916         },
1917         { &hf_fp_crci[4],
1918             { "CRCI",
1919               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x08,
1920               "CRC correctness indicator", HFILL
1921             }
1922         },
1923         { &hf_fp_crci[5],
1924             { "CRCI",
1925               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x04,
1926               "CRC correctness indicator", HFILL
1927             }
1928         },
1929         { &hf_fp_crci[6],
1930             { "CRCI",
1931               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x02,
1932               "CRC correctness indicator", HFILL
1933             }
1934         },
1935         { &hf_fp_crci[7],
1936             { "CRCI",
1937               "fp.crci", FT_UINT8, BASE_HEX, VALS(crci_vals), 0x01,
1938               "CRC correctness indicator", HFILL
1939             }
1940         },
1941         { &hf_fp_received_sync_ul_timing_deviation,
1942             { "Received SYNC UL Timing Deviation",
1943               "fp.rx-sync-ul-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
1944               "Received SYNC UL Timing Deviation", HFILL
1945             }
1946         },
1947         { &hf_fp_pch_pi,
1948             { "Paging Indication",
1949               "fp.pch.pi", FT_UINT8, BASE_DEC, VALS(paging_indication_vals), 0x01,
1950               "Indicates if the PI Bitmap is present", HFILL
1951             }
1952         },
1953         { &hf_fp_pch_tfi,
1954             { "TFI",
1955               "fp.pch.tfi", FT_UINT8, BASE_DEC, 0, 0x1f,
1956               "PCH Transport Format Indicator", HFILL
1957             }
1958         },
1959         { &hf_fp_fach_tfi,
1960             { "TFI",
1961               "fp.fach.tfi", FT_UINT8, BASE_DEC, 0, 0x1f,
1962               "Transport Format Indicator", HFILL
1963             }
1964         },
1965         { &hf_fp_transmit_power_level,
1966             { "Transmit Power Level",
1967               "fp.transmit-power-level", FT_UINT8, BASE_DEC, 0, 0x0,
1968               "Transmit Power Level", HFILL
1969             }
1970         },
1971         { &hf_fp_pdsch_set_id,
1972             { "PDSCH Set Id",
1973               "fp.pdsch-set-id", FT_UINT8, BASE_DEC, 0, 0x0,
1974               "A pointer to the PDSCH Set which shall be used to transmit", HFILL
1975             }
1976         },
1977         { &hf_fp_paging_indication_bitmap,
1978             { "Paging Indications bitmap",
1979               "fp.pch.pi-bitmap", FT_NONE, BASE_NONE, NULL, 0x0,
1980               "Paging Indication bitmap", HFILL
1981             }
1982         },
1983         { &hf_fp_rx_timing_deviation,
1984             { "Rx Timing Deviation",
1985               "fp.common.control.rx-timing-deviation", FT_UINT8, BASE_DEC, 0, 0x0,
1986               "Common Rx Timing Deviation", HFILL
1987             }
1988         },
1989         { &hf_fp_edch_header_crc,
1990             { "E-DCH Header CRC",
1991               "fp.edch.header-crc", FT_UINT16, BASE_HEX, 0, 0xfef,
1992               "E-DCH Header CRC", HFILL
1993             }
1994         },
1995         { &hf_fp_edch_fsn,
1996             { "FSN",
1997               "fp.edch.fsn", FT_UINT8, BASE_DEC, 0, 0x0f,
1998               "E-DCH Frame Sequence Number", HFILL
1999             }
2000         },
2001         { &hf_fp_edch_number_of_subframes,
2002             { "No of subframes",
2003               "fp.edch.no-of-subframes", FT_UINT8, BASE_DEC, 0, 0x0f,
2004               "E-DCH Number of subframes", HFILL
2005             }
2006         },
2007         { &hf_fp_edch_harq_retransmissions,
2008             { "No of HARQ Retransmissions",
2009               "fp.edch.no-of-harq-retransmissions", FT_UINT8, BASE_DEC, 0, 0x78,
2010               "E-DCH Number of HARQ retransmissions", HFILL
2011             }
2012         },
2013         { &hf_fp_edch_subframe_number,
2014             { "Subframe number",
2015               "fp.edch.subframe-number", FT_UINT8, BASE_DEC, 0, 0x07,
2016               "E-DCH Subframe number", HFILL
2017             }
2018         },
2019         { &hf_fp_edch_number_of_mac_es_pdus,
2020             { "Number of Mac-es PDUs",
2021               "fp.edch.number-of-mac-es-pdus", FT_UINT8, BASE_DEC, 0, 0xf0,
2022               "Number of Mac-es PDUs", HFILL
2023             }
2024         },
2025         { &hf_fp_edch_ddi,
2026             { "DDI",
2027               "fp.edch.ddi", FT_UINT8, BASE_DEC, 0, 0x0,
2028               "E-DCH Data Description Indicator", HFILL
2029             }
2030         },
2031         { &hf_fp_edch_subframe,
2032             { "Subframe",
2033               "fp.edch.subframe", FT_STRING, BASE_NONE, NULL, 0x0,
2034               "EDCH Subframe", HFILL
2035             }
2036         },
2037         { &hf_fp_edch_subframe_header,
2038             { "Subframe header",
2039               "fp.edch.subframe-header", FT_STRING, BASE_NONE, NULL, 0x0,
2040               "EDCH Subframe header", HFILL
2041             }
2042         },
2043         { &hf_fp_edch_number_of_mac_d_pdus,
2044             { "Number of Mac-d PDUs",
2045               "fp.edch.number-of-mac-d-pdus", FT_UINT8, BASE_DEC, 0, 0x0,
2046               "Number of Mac-d PDUs", HFILL
2047             }
2048         },
2049         { &hf_fp_edch_pdu_padding,
2050             { "Padding",
2051               "fp.edch-data-padding", FT_UINT8, BASE_DEC, 0, 0xc0,
2052               "E-DCH padding before PDU", HFILL
2053             }
2054         },
2055         { &hf_fp_edch_tsn,
2056             { "TSN",
2057               "fp.edch-tsn", FT_UINT8, BASE_DEC, 0, 0x3f,
2058               "E-DCH Transmission Sequence Number", HFILL
2059             }
2060         },
2061         { &hf_fp_edch_mac_es_pdu,
2062             { "MAC-es PDU",
2063               "fp.edch.mac-es-pdu", FT_NONE, BASE_NONE, NULL, 0x0,
2064               "MAC-es PDU", HFILL
2065             }
2066         },
2067         { &hf_fp_cmch_pi,
2068             { "CmCH-PI",
2069               "fp.cmch-pi", FT_UINT8, BASE_DEC, 0, 0x0f,
2070               "Common Transport Channel Priority Indicator", HFILL
2071             }
2072         },
2073         { &hf_fp_user_buffer_size,
2074             { "User buffer size",
2075               "fp.user-buffer-size", FT_UINT16, BASE_DEC, 0, 0x0,
2076               "User buffer size in octets", HFILL
2077             }
2078         },
2079         { &hf_fp_hsdsch_credits,
2080             { "HS-DSCH Credits",
2081               "fp.hsdsch-credits", FT_UINT16, BASE_DEC, 0, 0x07ff,
2082               "HS-DSCH Credits", HFILL
2083             }
2084         },
2085         { &hf_fp_hsdsch_max_macd_pdu_len,
2086             { "Max MAC-d PDU Length",
2087               "fp.hsdsch.max-macd-pdu-len", FT_UINT16, BASE_DEC, 0, 0xfff8,
2088               "Maximum MAC-d PDU Length in bits", HFILL
2089             }
2090         },
2091         { &hf_fp_hsdsch_interval,
2092             { "HS-DSCH Interval in milliseconds",
2093               "fp.hsdsch-interval", FT_UINT8, BASE_DEC, 0, 0x0,
2094               "HS-DSCH Interval in milliseconds", HFILL
2095             }
2096         },
2097         { &hf_fp_hsdsch_repetition_period,
2098             { "HS-DSCH Repetition Period",
2099               "fp.hsdsch-repetition-period", FT_UINT8, BASE_DEC, 0, 0x0,
2100               "HS-DSCH Repetition Period in milliseconds", HFILL
2101             }
2102         },
2103         { &hf_fp_hsdsch_data_padding,
2104             { "Padding",
2105               "fp.hsdsch-data-padding", FT_UINT8, BASE_DEC, 0, 0xf0,
2106               "HS-DSCH Repetition Period in milliseconds", HFILL
2107             }
2108         },
2109         { &hf_fp_hsdsch_new_ie_flags[0],
2110             { "DRT present",
2111               "fp.hsdsch.new-ie-flags", FT_UINT8, BASE_DEC, 0, 0x80,
2112               "DRT present", HFILL
2113             }
2114         },
2115         { &hf_fp_hsdsch_new_ie_flags[1],
2116             { "New IE present",
2117               "fp.hsdsch.new-ie-flags", FT_UINT8, BASE_DEC, 0, 0x40,
2118               "New IE present", HFILL
2119             }
2120         },
2121         { &hf_fp_hsdsch_new_ie_flags[2],
2122             { "New IE present",
2123               "fp.hsdsch.new-ie-flags", FT_UINT8, BASE_DEC, 0, 0x20,
2124               "New IE present", HFILL
2125             }
2126         },
2127         { &hf_fp_hsdsch_new_ie_flags[3],
2128             { "New IE present",
2129               "fp.hsdsch.new-ie-flags", FT_UINT8, BASE_DEC, 0, 0x10,
2130               "New IE present", HFILL
2131             }
2132         },
2133         { &hf_fp_hsdsch_new_ie_flags[4],
2134             { "New IE present",
2135               "fp.hsdsch.new-ie-flags", FT_UINT8, BASE_DEC, 0, 0x08,
2136               "New IE present", HFILL
2137             }
2138         },
2139         { &hf_fp_hsdsch_new_ie_flags[5],
2140             { "New IE present",
2141               "fp.hsdsch.new-ie-flags", FT_UINT8, BASE_DEC, 0, 0x04,
2142               "New IE present", HFILL
2143             }
2144         },
2145         { &hf_fp_hsdsch_new_ie_flags[6],
2146             { "New IE present",
2147               "fp.hsdsch.new-ie-flags", FT_UINT8, BASE_DEC, 0, 0x02,
2148               "New IE present", HFILL
2149             }
2150         },
2151         { &hf_fp_hsdsch_new_ie_flags[7],
2152             { "New IE present",
2153               "fp.hsdsch.new-ie-flags", FT_UINT8, BASE_DEC, 0, 0x01,
2154               "New IE present", HFILL
2155             }
2156         },
2157         { &hf_fp_hsdsch_drt,
2158             { "DRT",
2159               "fp.hsdsch.drt", FT_UINT8, BASE_DEC, 0, 0xf0,
2160               "Delay Reference Time", HFILL
2161             }
2162         },
2163         { &hf_fp_timing_advance,
2164             { "Timing advance",
2165               "fp.timing-advance", FT_UINT8, BASE_DEC, 0, 0x3f,
2166               "Timing advance in chips", HFILL
2167             }
2168         },
2169         { &hf_fp_num_of_pdu,
2170             { "Number of PDUs",
2171               "fp.hsdsch.num-of-pdu", FT_UINT8, BASE_DEC, 0, 0x0,
2172               "Number of PDUs in the payload", HFILL
2173             }
2174         },
2175         { &hf_fp_mac_d_pdu_len,
2176             { "MAC-d PDU Length",
2177               "fp.hsdsch.mac-d-pdu-len", FT_UINT16, BASE_DEC, 0, 0xfff8,
2178               "MAC-d PDU Length in bits", HFILL
2179             }
2180         },
2181         { &hf_fp_mac_d_pdu,
2182             { "MAC-d PDU",
2183               "fp.mac-d-pdu", FT_NONE, BASE_NONE, NULL, 0x0,
2184               "MAC-d PDU", HFILL
2185             }
2186         },
2187         { &hf_fp_data,
2188             { "Data",
2189               "fp.data", FT_STRING, BASE_NONE, NULL, 0x0,
2190               "Data", HFILL
2191             }
2192         },
2193         { &hf_fp_crcis,
2194             { "CRCIs",
2195               "fp.crcis", FT_STRING, BASE_NONE, NULL, 0x0,
2196               "CRC Indicators for uplink TBs", HFILL
2197             }
2198         },
2199         { &hf_fp_t1,
2200             { "T1",
2201               "fp.t1", FT_UINT24, BASE_DEC, NULL, 0x0,
2202               "RNC frame number indicating time it sends frame", HFILL
2203             }
2204         },
2205         { &hf_fp_t2,
2206             { "T2",
2207               "fp.t2", FT_UINT24, BASE_DEC, NULL, 0x0,
2208               "NodeB frame number indicating time it received DL Sync", HFILL
2209             }
2210         },
2211         { &hf_fp_t3,
2212             { "T3",
2213               "fp.t3", FT_UINT24, BASE_DEC, NULL, 0x0,
2214               "NodeB frame number indicating time it sends frame", HFILL
2215             }
2216         },
2217         { &hf_fp_ul_sir_target,
2218             { "UL_SIR_TARGET",
2219               "fp.ul-sir_target", FT_FLOAT, BASE_DEC, 0, 0x0,
2220               "Value (in dB) of the SIR target to be used by the UL inner loop power control", HFILL
2221             }
2222         },
2223
2224     };
2225
2226     static gint *ett[] =
2227     {
2228         &ett_fp,
2229         &ett_fp_data,
2230         &ett_fp_crcis,
2231         &ett_fp_edch_subframe_header,
2232         &ett_fp_edch_subframe
2233     };
2234
2235     /* Register protocol. */
2236     proto_fp = proto_register_protocol("FP", "FP", "fp");
2237     proto_register_field_array(proto_fp, hf, array_length(hf));
2238     proto_register_subtree_array(ett, array_length(ett));
2239
2240     /* Allow other dissectors to find this one by name. */
2241     register_dissector("fp", dissect_fp, proto_fp);
2242 }
2243
2244
2245 void proto_reg_handoff_fp(void)
2246 {
2247 }
2248