5346d2d1fc3b009a81342b5b2d44ad78cb0c86fe
[obnox/wireshark/wip.git] / epan / dissectors / packet-gsm_a_rr.c
1 /* packet-gsm_a_rr.c
2  * Routines for GSM A Interface (actually A-bis really) RR dissection - A.K.A. GSM layer 3 Radio Resource Protocol
3  *
4  * Copyright 2003, Michael Lum <mlum [AT] telostech.com>
5  * In association with Telos Technology Inc.
6  *
7  * Added Dissection of Radio Resource Management Information Elements
8  * and other enhancements and fixes.
9  * Copyright 2005 - 2006, Anders Broman [AT] ericsson.com
10  *
11  * Title                3GPP                    Other
12  *
13  *   Reference [3]
14  *   Mobile radio interface Layer 3 specification;
15  *   Core network protocols;
16  *   Stage 3
17  *   (3GPP TS 24.008 version 4.7.0 Release 4)
18  *   (ETSI TS 124 008 V6.8.0 (2005-03))
19  *
20  *   Reference [4]
21  *   Mobile radio interface layer 3 specification;
22  *   Radio Resource Control Protocol
23  *   (GSM 04.18 version 8.4.1 Release 1999)
24  *   (3GPP TS 04.18 version 8.26.0 Release 1999)
25  *
26  * $Id$
27  *
28  * Wireshark - Network traffic analyzer
29  * By Gerald Combs <gerald@wireshark.org>
30  * Copyright 1998 Gerald Combs
31  *
32  * This program is free software; you can redistribute it and/or
33  * modify it under the terms of the GNU General Public License
34  * as published by the Free Software Foundation; either version 2
35  * of the License, or (at your option) any later version.
36  *
37  * This program is distributed in the hope that it will be useful,
38  * but WITHOUT ANY WARRANTY; without even the implied warranty of
39  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
40  * GNU General Public License for more details.
41  *
42  * You should have received a copy of the GNU General Public License
43  * along with this program; if not, write to the Free Software
44  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
45  */
46
47 #ifdef HAVE_CONFIG_H
48 # include "config.h"
49 #endif
50
51 #include <stdlib.h>
52
53 #include <string.h>
54
55 #include <epan/packet.h>
56 #include <epan/prefs.h>
57 #include <epan/tap.h>
58 #include <epan/asn1.h>
59
60 #include "packet-bssap.h"
61 #include "packet-sccp.h"
62 #include "packet-ber.h"
63 #include "packet-q931.h"
64 #include "packet-gsm_a_common.h"
65 #include "packet-ipv6.h"
66 #include "packet-e212.h"
67 #include "packet-ppp.h"
68
69 static dissector_handle_t rrc_irat_ho_info_handle;
70 static dissector_handle_t rrc_irat_ho_to_utran_cmd_handle;
71
72 #define PADDING_BYTE 0x2B
73
74 gboolean gsm_a_rr_is_bit_high(tvbuff_t *tvb, gint bit_offset)
75 {
76     guint8 bit_mask = 0x80 >> (bit_offset & 0x07);
77     if ((tvb_get_guint8(tvb,bit_offset >> 3) & bit_mask) != (PADDING_BYTE & bit_mask))
78         return TRUE;
79     return FALSE;
80 }
81
82 /* PROTOTYPES/FORWARDS */
83
84 const value_string gsm_a_dtap_msg_rr_strings[] = {
85     { 0x3c, "Reserved" },
86     { 0x3b, "Additional Assignment" },
87     { 0x3f, "Immediate Assignment" },
88     { 0x39, "Immediate Assignment Extended" },
89     { 0x3a, "Immediate Assignment Reject" },
90
91     { 0x48, "DTM Assignment Failure" },
92     { 0x49, "DTM Reject" },
93     { 0x4a, "DTM Request" },
94     { 0x4b, "Main DCCH Assignment Command" },
95     { 0x4c, "Packet Assignment Command" },
96
97     { 0x35, "Ciphering Mode Command" },
98     { 0x32, "Ciphering Mode Complete" },
99
100     { 0x30, "Configuration Change Command" },
101     { 0x31, "Configuration Change Ack." },
102     { 0x33, "Configuration Change Reject" },
103
104     { 0x2e, "Assignment Command" },
105     { 0x29, "Assignment Complete" },
106     { 0x2f, "Assignment Failure" },
107     { 0x2b, "Handover Command" },
108     { 0x2c, "Handover Complete" },
109     { 0x28, "Handover Failure" },
110     { 0x2d, "Physical Information" },
111     { 0x4d, "DTM Assignment Command" },
112
113     { 0x08, "RR-cell Change Order" },
114     { 0x23, "PDCH Assignment Command" },
115
116     { 0x0d, "Channel Release" },
117     { 0x0a, "Partial Release" },
118     { 0x0f, "Partial Release Complete" },
119
120     { 0x21, "Paging Request Type 1" },
121     { 0x22, "Paging Request Type 2" },
122     { 0x24, "Paging Request Type 3" },
123     { 0x27, "Paging Response" },
124     { 0x20, "Notification/NCH" },
125     { 0x25, "Reserved" },
126     { 0x26, "Notification/Response" },
127
128     { 0x0b, "Reserved" },
129
130 #if 0
131 /* ETSI TS 101 503 V8.5.0 Seems to give Other def for this Messages??? */
132     { 0xc0, "Utran Classmark Change" }, CONFLICTS WITH Handover To UTRAN Command
133     { 0xc1, "UE RAB Preconfiguration" },
134     { 0xc2, "cdma2000 Classmark Change" },
135 #endif
136
137     /* ETSI TS 101 503 V8.5.0 */
138     { 0x60, "Utran Classmark Change" },
139     { 0x62, "cdma2000 Classmark Change" },
140     { 0x63, "Inter System to UTRAN Handover Command" },
141     { 0x64, "Inter System to cdma2000 Handover Command" },
142     { 0x18, "System Information Type 8" },
143     { 0x19, "System Information Type 1" },
144     { 0x1a, "System Information Type 2" },
145     { 0x1b, "System Information Type 3" },
146     { 0x1c, "System Information Type 4" },
147     { 0x1d, "System Information Type 5" },
148     { 0x1e, "System Information Type 6" },
149     { 0x1f, "System Information Type 7" },
150
151     { 0x02, "System Information Type 2bis" },
152     { 0x03, "System Information Type 2ter" },
153     { 0x07, "System Information Type 2quater" },
154     { 0x05, "System Information Type 5bis" },
155     { 0x06, "System Information Type 5ter" },
156     { 0x04, "System Information Type 9" },
157     { 0x00, "System Information Type 13" },
158
159     { 0x3d, "System Information Type 16" },
160     { 0x3e, "System Information Type 17" },
161
162     { 0x40, "System Information Type 18" },
163     { 0x41, "System Information Type 19" },
164     { 0x42, "System Information Type 20" },
165
166     { 0x10, "Channel Mode Modify" },
167     { 0x12, "RR Status" },
168     { 0x17, "Channel Mode Modify Acknowledge" },
169     { 0x14, "Frequency Redefinition" },
170     { 0x15, "Measurement Report" },
171     { 0x16, "Classmark Change" },
172     { 0x13, "Classmark Enquiry" },
173     { 0x36, "Extended Measurement Report" },
174     { 0x37, "Extended Measurement Order" },
175     { 0x34, "GPRS Suspension Request" },
176
177     { 0x09, "VGCS Uplink Grant" },
178     { 0x0e, "Uplink Release" },
179     { 0x0c, "Reserved" },
180     { 0x2a, "Uplink Busy" },
181     { 0x11, "Talker Indication" },
182
183     { 0xc0, "UTRAN Classmark Change/Handover To UTRAN Command" }, /* spec conflict */
184
185     { 0x38, "Application Information" },
186
187     {    0, NULL }
188 };
189
190 const value_string gsm_rr_elem_strings[] = {
191     /* Radio Resource Management Information Elements 10.5.2, most are from 10.5.1 */
192     { 0x00, "BA Range" },                                                       /* [3]  10.5.2.1a BA Range */
193     { 0x00, "Cell Channel Description" },                                       /* [3]  10.5.2.1b */
194     { 0x00, "BA List Pref" },                                                   /* [3]  10.5.2.1c BA List Pref */
195     { 0x00, "UTRAN Frequency List" },                                           /* [3]  10.5.2.1d UTRAN Frequency List */
196     { 0x00, "Cell Selection Indicator after Release of all TCH and SDCCH" },    /* [3]  10.5.2.1e       Cell selection indicator after release of all TCH and SDCCH IE */
197     { 0x00, "Cell Description" },                                               /* 10.5.2.2  */
198     { 0x00, "Cell Options (BCCH)" },                                            /* [3]  10.5.2.3        Cell Options (BCCH) */
199     { 0x00, "Cell Options (SACCH)" },                                           /* [3]  10.5.2.3a       Cell Options (SACCH) */
200     { 0x00, "Cell Selection Parameters" },                                      /* [3]  10.5.2.4        Cell Selection Parameters */
201 /* [3]  10.5.2.4a       (void) */
202     { 0x00, "Channel Description" },                                            /* 10.5.2.5      */
203     { 0x00, "Channel Description 2" },                                          /* 10.5.2.5a */
204     { 0x00, "Channel Description 3" },                                          /* 10.5.2.5c */
205     { 0x00, "Channel Mode" },                                                   /* [3]  10.5.2.6 */
206     { 0x00, "Channel Mode 2" },                                                 /* [3]  10.5.2.7 */
207     { 0x00, "UTRAN Classmark" },                                                /* [3]  10.5.2.7a       */
208 /* [3]  10.5.2.7b       (void) */
209     { 0x00, "Classmark Enquiry Mask" },                                         /* [3]  10.5.2.7c */
210 /* [3]  10.5.2.7d       GERAN Iu Mode Classmark information element */
211     { 0x00, "Channel Needed"},                                                  /* [3]  10.5.2.8        */
212     /* [3]  10.5.2.8a   (void) */
213     /* [3]  10.5.2.8b   Channel Request Description 2 */
214     /* Pos 20 */
215     { 0x00, "Cipher Mode Setting" },                                            /* [3]  10.5.2.9        */
216     { 0x00, "Cipher Mode Response" },                                           /* [3]  10.5.2.10       */
217     { 0x00, "Control Channel Description" },                                    /* [3]  10.5.2.11       Control Channel Description */
218 /* [3]  10.5.2.11a      DTM Information Details */
219     { 0x00, "Dynamic ARFCN Mapping" },                                          /* [3]  10.5.2.11b      */
220     { 0x00, "Frequency Channel Sequence" },                                     /* [3]  10.5.2.12       */
221     { 0x00, "Frequency List" },                                                 /* 10.5.2.13            */
222     { 0x00, "Frequency Short List" },                                           /* 10.5.2.14            */
223     { 0x00, "Frequency Short List2" },                                          /* 10.5.2.14a           */
224 /* [3]  10.5.2.14b      Group Channel Description */
225     { 0x00, "GPRS Resumption" },                                                /* [3]  10.5.2.14c      GPRS Resumption */
226     { 0x00, "GPRS Broadcast Information" },                                     /* [3]  10.5.2.14d      GPRS broadcast information */
227 /* [3]  10.5.2.14e      Enhanced DTM CS Release Indication */
228     { 0x00, "Handover Reference" },                                             /* 10.5.2.15            */
229     { 0x00, "IA Rest Octets" },                                                 /* [3] 10.5.2.16        */
230     { 0x00, "IAR Rest Octets" },                                                /* [3] 10.5.2.17 IAR Rest Octets */
231     { 0x00, "IAX Rest Octets" },                                                /* [3] 10.5.2.18 IAX Rest Octets */
232     { 0x00, "L2 Pseudo Length" },                                               /* [3] 10.5.2.19        */
233     { 0x00, "Measurement Results" },                                            /* [3] 10.5.2.20 Measurement Results */
234 /*
235  * [3] 10.5.2.20a GPRS Measurement Results
236  */
237     { 0x00, "Mobile Allocation" },                                              /* [3] 10.5.2.21        */
238     { 0x00, "Mobile Time Difference" },                                         /* [3] 10.5.2.21a       */
239     { 0x00, "MultiRate configuration" },                                        /* [3] 10.5.2.21aa      */
240     /* Pos 30 */
241     { 0x00, "Multislot Allocation" },                                           /* [3] 10.5.2.21b       */
242     /*
243      * [3] 10.5.2.21c NC mode
244      */
245     { 0x00, "Neighbour Cell Description" },                                     /* [3] 10.5.2.22 Neighbour Cell Description */
246     { 0x00, "Neighbour Cell Description 2" },                                   /* [3] 10.5.2.22a Neighbour Cell Description 2 */
247 /*
248  * [3] 10.5.2.22b (void)
249  * [3] 10.5.2.22c NT/N Rest Octets */
250     { 0x00, "P1 Rest Octets" },                                                 /* [3] 10.5.2.23 P1 Rest Octets */
251     { 0x00, "P2 Rest Octets" },                                                 /* [3] 10.5.2.24 P2 Rest Octets */
252     { 0x00, "P3 Rest Octets" },                                                 /* [3] 10.5.2.25 P3 Rest Octets */
253     { 0x00, "Packet Channel Description" },                                     /* [3] 10.5.2.25a       */
254     { 0x00, "Dedicated mode or TBF" },                                          /* [3] 10.5.2.25b */
255     /* [3] 10.5.2.25c RR Packet Uplink Assignment
256      * [3] 10.5.2.25d RR Packet Downlink Assignment */
257     { 0x00, "Page Mode" },                                                      /* [3] 10.5.2.26  */
258 /*
259  * [3] 10.5.2.26a (void)
260  * [3] 10.5.2.26b (void)
261  * [3] 10.5.2.26c (void)
262  * [3] 10.5.2.26d (void)
263  */
264     { 0x00, "NCC Permitted" },                                                  /* [3] 10.5.2.27 NCC Permitted */
265     { 0x00, "Power Command" },                                                  /* 10.5.2.28 */
266     { 0x00, "Power Command and access type" },                                  /* 10.5.2.28a */
267     { 0x00, "RACH Control Parameters" },                                        /* [3] 10.5.2.29 RACH Control Parameters */
268     { 0x00, "Request Reference" },                                              /* [3] 10.5.2.30 Request Reference */
269     { 0x00, "RR Cause" },                                                       /* 10.5.2.31 */
270     { 0x00, "Synchronization Indication" },                                     /* 10.5.2.39 */
271     { 0x00, "SI 1 Rest Octets" },                                               /* [3] 10.5.2.32 */
272 /* [3] 10.5.2.33 SI 2bis Rest Octets */
273     { 0x00, "SI 2ter Rest Octets" },                                            /* [3] 10.5.2.33a */
274     { 0x00, "SI 2quater Rest Octets" },                                         /* [3] 10.5.2.33b */
275     { 0x00, "SI 3 Rest Octets" },                                               /* [3] 10.5.2.34 */
276     { 0x00, "SI 4 Rest Octets" },                                               /* [3] 10.5.2.35 */
277     { 0x00, "SI 6 Rest Octets" },                                               /* [3] 10.5.2.35a */
278 /* [3] 10.5.2.36 SI 7 Rest Octets
279  * [3] 10.5.2.37 SI 8 Rest Octets
280  * [3] 10.5.2.37a SI 9 Rest Octets
281  */
282     { 0x00, "SI 13 Rest Octets" },                                              /* [3] 10.5.2.37b */
283 /* [3] 10.5.2.37c (void)
284  * [3] 10.5.2.37d (void)
285  * [3] 10.5.2.37e SI 16 Rest Octets
286  * [3] 10.5.2.37f SI 17 Rest Octets
287  * [3] 10.5.2.37g SI 19 Rest Octets
288  * [3] 10.5.2.37h SI 18 Rest Octets
289  * [3] 10.5.2.37i SI 20 Rest Octets */
290     { 0x00, "Starting Time" },                                                  /* [3] 10.5.2.38 Starting Time  */
291     { 0x00, "Timing Advance" },                                                 /* [3] 10.5.2.40 Timing Advance */
292     { 0x00, "Time Difference" },                                                /* [3] 10.5.2.41 Time Difference */
293     { 0x00, "TLLI" },                                                           /* [3] 10.5.2.41a TLLI  */
294     { 0x00, "TMSI/P-TMSI" },                                                    /* [3] 10.5.2.42 TMSI/P-TMSI */
295     { 0x00, "VGCS target mode Indication" },                                    /* [3] 10.5.2.42a */
296     /* Pos 40 */
297     { 0x00, "VGCS Ciphering Parameters" },                                      /* [3] 10.5.2.42b */
298     { 0x00, "Wait Indication" },                                                /* [3] 10.5.2.43 Wait Indication */
299 /* [3] 10.5.2.44 SI10 rest octets $(ASCI)$ */
300     { 0x00, "Extended Measurement Results" },                                   /* [3] 10.5.2.45 Extended Measurement Results */
301     { 0x00, "Extended Measurement Frequency List" },                            /* [3] 10.5.2.46 Extended Measurement Frequency List */
302     { 0x00, "Suspension Cause" },                                               /* [3] 10.5.2.47                                                                */
303     { 0x00, "APDU ID" },                                                        /* [3] 10.5.2.48 APDU ID */
304     { 0x00, "APDU Flags" },                                                     /* [3] 10.5.2.49 APDU Flags */
305     { 0x00, "APDU Data" },                                                      /* [3] 10.5.2.50 APDU Data */
306     { 0x00, "Handover to UTRAN Command" },                                      /* [3] 10.5.2.51 Handover To UTRAN Command */
307 /* [3] 10.5.2.52 Handover To cdma2000 Command
308  * [3] 10.5.2.53 (void)
309  * [3] 10.5.2.54 (void)
310  * [3] 10.5.2.55 (void)
311  * [3] 10.5.2.56 3G Target Cell */
312     { 0x00, "Service Support" },                                                /* [3] 10.5.2.57        */
313     /* 10.5.2.58 MBMS p-t-m Channel Description */
314     { 0x00, "Dedicated Service Information" },                                  /* [3] 10.5.2.59        */
315 /*
316  * 10.5.2.60 MPRACH Description
317  * 10.5.2.61 Restriction Timer
318  * 10.5.2.62 MBMS Session Identity
319  * 10.5.2.63 Reduced group or broadcast call reference
320  * 10.5.2.64 Talker Priority status
321  * 10.5.2.65 Talker Identity
322  * 10.5.2.66 Token
323  * 10.5.2.67 PS Cause
324  * 10.5.2.68 VGCS AMR Configuration
325  */
326     { 0x00, "Carrier Indication" },                                             /* 10.5.2.69 Carrier Indication */
327     {    0, NULL }
328 };
329
330 const value_string gsm_rr_rest_octets_elem_strings[] = {
331     /* RR Rest Octets information elements */
332     { 0, "UTRAN FDD Description" },
333     { 0, "UTRAN TDD Description" },
334     { 0, "3G Measurement Parameters Description" },
335     { 0, "3G Additional Measurement Parameters Description" },
336     { 0, "Measurement Parameters Description" },
337     { 0, "GPRS Real Time Difference Description" },
338     { 0, "GPRS BSIC Description" },
339     { 0, "GPRS Report Priority Description" },
340     { 0, "GPRS Measurement Parameters Description" },
341     { 0, "NC Measurement Parameters" },
342     { 0, "SI2q Extension Information" },
343     { 0, "CCN Support Description" },
344     { 0, "3G Neighbour Cell Description" },
345     { 0, "FDD Cell Information Field" },
346     { 0, "TDD Cell Information Field" },
347     { 0, "GPRS 3G Measurement Parameters Description" },
348     { 0, "3G Additional Measurement Parameters Description 2" },
349     { 0, "Priority and E-UTRAN Parameters Description" },
350     { 0, "3G Priority Parameters Description" },
351     { 0, "E-UTRAN Parameters Description" },
352     { 0, "E-UTRAN Neighbour Cells" },
353     { 0, "E-UTRAN Not Allowed Cells" },
354     { 0, "E-UTRAN PCID to TA mapping" },
355     { 0, "3G CSG Description" },
356     { 0, "E-UTRAN CSG Description" },
357     { 0, "Optional Selection Parameters" },
358     { 0, "GPRS Indicator" },
359     { 0, "SI4 Rest Octets_O" },
360     { 0, "SI4 Rest Octets_S" },
361     { 0, "LSA Parameters" },
362     { 0, "LSA ID Information" },
363     { 0, "PCH and NCH Info" },
364     { 0, "VBS/VGCS Options" },
365     { 0, "GPRS Mobile Allocation" },
366     { 0, "GPRS Cell Options" },
367     { 0, "GPRS Cell Options Extension Information" },
368     { 0, "GPRS Power Control Parameters" },
369     { 0, "PBCCH Description" },
370     { 0, "GSM Description" },
371     { 0, "Real Time Difference Description" },
372     { 0, "BSIC Description" },
373     { 0, "Report Priority Description" },
374     { 0, "CDMA2000 Description" },
375     { 0, "Serving cell data" },
376     { 0, "Repeated Invalid BSIC Information" },
377     { 0, "Bitmap Type Reporting" },
378     { 0, NULL }
379 };
380
381
382 /* RR cause value (octet 2) TS 44.018 6.11.0*/
383 static const value_string gsm_a_rr_RR_cause_vals[] = {
384     {    0, "Normal event"},
385     {    1, "Abnormal release, unspecified"},
386     {    2, "Abnormal release, channel unacceptable"},
387     {    3, "Abnormal release, timer expired"},
388     {    4, "Abnormal release, no activity on the radio path"},
389     {    5, "Preemptive release"},
390     {    6, "UTRAN configuration unknown"},
391     {    8, "Handover impossible, timing advance out of range"},
392     {    9, "Channel mode unacceptable"},
393     {   10, "Frequency not implemented"},
394     {   13, "Originator or talker leaving group call area"},
395     {   12, "Lower layer failure"},
396     { 0x41, "Call already cleared"},
397     { 0x5f, "Semantically incorrect message"},
398     { 0x60, "Invalid mandatory information"},
399     { 0x61, "Message type non-existent or not implemented"},
400     { 0x62, "Message type not compatible with protocol state"},
401     { 0x64, "Conditional IE error"},
402     { 0x65, "No cell allocation available"},
403     { 0x6f, "Protocol error unspecified"},
404     { 0,        NULL }
405 };
406
407 static const value_string gsm_a_algorithm_identifier_vals[] = {
408     { 0, "Cipher with algorithm A5/1"},
409     { 1, "Cipher with algorithm A5/2"},
410     { 2, "Cipher with algorithm A5/3"},
411     { 3, "Cipher with algorithm A5/4"},
412     { 4, "Cipher with algorithm A5/5"},
413     { 5, "Cipher with algorithm A5/6"},
414     { 6, "Cipher with algorithm A5/7"},
415     { 7, "Reserved"},
416     { 0, NULL }
417 };
418
419
420 #define DTAP_PD_MASK            0x0f
421 #define DTAP_SKIP_MASK          0xf0
422 #define DTAP_TI_MASK            DTAP_SKIP_MASK
423 #define DTAP_TIE_PRES_MASK      0x07                    /* after TI shifted to right */
424 #define DTAP_TIE_MASK           0x7f
425
426 #define DTAP_RR_IEI_MASK        0xff
427
428 /* Initialize the protocol and registered fields */
429 static int proto_a_ccch = -1;
430 static int proto_a_sacch = -1;
431
432 static int hf_gsm_a_dtap_msg_rr_type = -1;
433 int hf_gsm_a_rr_elem_id = -1;
434
435 static int hf_gsm_a_sacch_msg_rr_type = -1;
436
437 static int hf_gsm_a_bcc = -1;
438 static int hf_gsm_a_ncc = -1;
439 static int hf_gsm_a_bcch_arfcn = -1;
440 static int hf_gsm_a_rr_range_nb = -1;
441 static int hf_gsm_a_rr_range_lower = -1;
442 static int hf_gsm_a_rr_range_higher = -1;
443 static int hf_gsm_a_rr_ba_list_pref_length = -1;
444 static int hf_gsm_a_rr_ba_freq = -1;
445 static int hf_gsm_a_rr_utran_freq_list_length = -1;
446 static int hf_gsm_a_rr_ho_ref_val       = -1;
447 static int hf_gsm_a_rr_L2_pseudo_len = -1;
448 static int hf_gsm_a_rr_ba_used = -1;
449 static int hf_gsm_a_rr_dtx_used = -1;
450 static int hf_gsm_a_rr_3g_ba_used = -1;
451 static int hf_gsm_a_rr_meas_valid = -1;
452 static int hf_gsm_a_rr_rxlev_full_serv_cell = -1;
453 static int hf_gsm_a_rr_rxlev_sub_serv_cell = -1;
454 static int hf_gsm_a_rr_rxqual_full_serv_cell = -1;
455 static int hf_gsm_a_rr_rxqual_sub_serv_cell = -1;
456 static int hf_gsm_a_rr_no_ncell_m = -1;
457 static int hf_gsm_a_rr_rxlev_ncell = -1;
458 static int hf_gsm_a_rr_bcch_freq_ncell = -1;
459 static int hf_gsm_a_rr_bsic_ncell = -1;
460 static int hf_gsm_a_rr_mobile_time_difference = -1;
461 static int hf_gsm_a_rr_pow_cmd_atc = -1;
462 static int hf_gsm_a_rr_pow_cmd_epc = -1;
463 static int hf_gsm_a_rr_page_mode = -1;
464 static int hf_gsm_a_rr_dedicated_mode_or_tbf = -1;
465 static int hf_gsm_a_rr_pow_cmd_fpcepc = -1;
466 static int hf_gsm_a_rr_pow_cmd_powlev = -1;
467 static int hf_gsm_a_rr_sync_ind_nci = -1;
468 static int hf_gsm_a_rr_sync_ind_rot = -1;
469 static int hf_gsm_a_rr_sync_ind_si = -1;
470 static int hf_gsm_a_rr_format_id = -1;
471 static int hf_gsm_a_rr_format_id2 = -1;
472 static int hf_gsm_a_rr_channel_mode = -1;
473 static int hf_gsm_a_rr_channel_mode2 = -1;
474 static int hf_gsm_a_rr_sc = -1;
475 static int hf_gsm_a_algorithm_id = -1;
476 static int hf_gsm_a_rr_cr = -1;
477 static int hf_gsm_a_rr_multirate_speech_ver = -1;
478 static int hf_gsm_a_rr_NCSB = -1;
479 static int hf_gsm_a_rr_ICMI = -1;
480 static int hf_gsm_a_rr_start_mode = -1;
481 static int hf_gsm_a_rr_timing_adv = -1;
482 static int hf_gsm_a_rr_time_diff = -1;
483 static int hf_gsm_a_rr_tlli = -1;
484 static int hf_gsm_a_rr_tmsi_ptmsi = -1;
485 static int hf_gsm_a_rr_target_mode = -1;
486 static int hf_gsm_a_rr_wait_indication = -1;
487 static int hf_gsm_a_rr_seq_code = -1;
488 static int hf_gsm_a_rr_group_cipher_key_number = -1;
489 static int hf_gsm_a_rr_MBMS_multicast = -1;
490 static int hf_gsm_a_rr_MBMS_broadcast = -1;
491 static int hf_gsm_a_rr_last_segment = -1;
492 static int hf_gsm_a_rr_carrier_ind = -1;
493 static int hf_gsm_a_rr_ra = -1;
494 static int hf_gsm_a_rr_T1prim = -1;
495 static int hf_gsm_a_rr_T3 = -1;
496 static int hf_gsm_a_rr_T2 = -1;
497 static int hf_gsm_a_rr_rfn = -1;
498 static int hf_gsm_a_rr_RR_cause = -1;
499 static int hf_gsm_a_rr_cm_cng_msg_req = -1;
500 static int hf_gsm_a_rr_utran_cm_cng_msg_req = -1;
501 static int hf_gsm_a_rr_cdma200_cm_cng_msg_req = -1;
502 static int hf_gsm_a_rr_geran_iu_cm_cng_msg_req = -1;
503 int hf_gsm_a_rr_chnl_needed_ch1 = -1;
504 static int hf_gsm_a_rr_chnl_needed_ch2 = -1;
505 static int hf_gsm_a_rr_chnl_needed_ch3 = -1;
506 static int hf_gsm_a_rr_chnl_needed_ch4 = -1;
507 static int hf_gsm_a_rr_suspension_cause = -1;
508 static int hf_gsm_a_rr_apdu_id = -1;
509 static int hf_gsm_a_rr_apdu_flags = -1;
510 static int hf_gsm_a_rr_apdu_data = -1;
511 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b8 = -1;
512 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b7 = -1;
513 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b6 = -1;
514 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b5 = -1;
515 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b4 = -1;
516 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b3 = -1;
517 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b2 = -1;
518 static int hf_gsm_a_rr_set_of_amr_codec_modes_v1_b1 = -1;
519 static int hf_gsm_a_rr_set_of_amr_codec_modes_v2_b5 = -1;
520 static int hf_gsm_a_rr_set_of_amr_codec_modes_v2_b4 = -1;
521 static int hf_gsm_a_rr_set_of_amr_codec_modes_v2_b3 = -1;
522 static int hf_gsm_a_rr_set_of_amr_codec_modes_v2_b2 = -1;
523 static int hf_gsm_a_rr_set_of_amr_codec_modes_v2_b1 = -1;
524 static int hf_gsm_a_rr_amr_threshold = -1;
525 static int hf_gsm_a_rr_amr_hysteresis = -1;
526 static int hf_gsm_a_rr_pwrc = -1;
527 static int hf_gsm_a_rr_dtx_bcch = -1;
528 static int hf_gsm_a_rr_dtx_sacch = -1;
529 static int hf_gsm_a_rr_radio_link_timeout = -1;
530 static int hf_gsm_a_rr_cell_reselect_hyst = -1;
531 static int hf_gsm_a_rr_ms_txpwr_max_cch = -1;
532 static int hf_gsm_a_rr_acs = -1;
533 static int hf_gsm_a_rr_neci = -1;
534 static int hf_gsm_a_rr_rxlev_access_min = -1;
535 static int hf_gsm_a_rr_mscr = -1;
536 static int hf_gsm_a_rr_att = -1;
537 static int hf_gsm_a_rr_ccch_conf = -1;
538 static int hf_gsm_a_rr_cbq3 = -1;
539 static int hf_gsm_a_rr_bs_pa_mfrms = -1;
540 static int hf_gsm_a_rr_bs_ag_blks_res = -1;
541 static int hf_gsm_a_rr_t3212 = -1;
542 static int hf_gsm_a_rr_dyn_arfcn_length = -1;
543 static int hf_gsm_a_rr_gsm_band = -1;
544 static int hf_gsm_a_rr_arfcn_first = -1;
545 static int hf_gsm_a_rr_band_offset = -1;
546 static int hf_gsm_a_rr_arfcn_range = -1;
547 static int hf_gsm_a_rr_lowest_arfcn = -1;
548 static int hf_gsm_a_rr_inc_skip_arfcn = -1;
549 static int hf_gsm_a_rr_gprs_resumption_ack = -1;
550 static int hf_gsm_a_rr_ext_ind = -1;
551 static int hf_gsm_a_rr_ba_ind = -1;
552 static int hf_gsm_a_rr_multiband_reporting = -1;
553 static int hf_gsm_a_rr_ncc_permitted = -1;
554 static int hf_gsm_a_rr_max_retrans = -1;
555 static int hf_gsm_a_rr_tx_integer = -1;
556 static int hf_gsm_a_rr_cell_barr_access = -1;
557 static int hf_gsm_a_rr_re = -1;
558 static int hf_gsm_a_rr_acc = -1;
559 static int hf_gsm_a_rr_nch_position = -1;
560 static int hf_gsm_a_rr_si2ter_mp_change_mark = -1;
561 static int hf_gsm_a_rr_si2ter_3g_change_mark = -1;
562 static int hf_gsm_a_rr_si2ter_index = -1;
563 static int hf_gsm_a_rr_si2ter_count = -1;
564 static int hf_gsm_a_rr_fdd_uarfcn = -1;
565 static int hf_gsm_a_rr_bandwidth_fdd = -1;
566 static int hf_gsm_a_rr_tdd_uarfcn = -1;
567 static int hf_gsm_a_rr_bandwidth_tdd = -1;
568 static int hf_gsm_a_rr_arfcn = -1;
569 static int hf_gsm_a_rr_bsic = -1;
570 static int hf_gsm_a_rr_qsearch_i = -1;
571 static int hf_gsm_a_rr_fdd_qoffset = -1;
572 static int hf_gsm_a_rr_fdd_qmin = -1;
573 static int hf_gsm_a_rr_tdd_qoffset = -1;
574 static int hf_gsm_a_rr_fdd_qmin_offset = -1;
575 static int hf_gsm_a_rr_fdd_rscpmin = -1;
576 static int hf_gsm_a_rr_3g_ba_ind = -1;
577 static int hf_gsm_a_rr_mp_change_mark = -1;
578 static int hf_gsm_a_rr_si2quater_index = -1;
579 static int hf_gsm_a_rr_si2quater_count = -1;
580 static int hf_gsm_a_rr_gsm_report_type = -1;
581 static int hf_gsm_a_rr_serving_band_reporting = -1;
582 static int hf_gsm_a_rr_frequency_scrolling = -1;
583 static int hf_gsm_a_rr_rep_priority = -1;
584 static int hf_gsm_a_rr_report_type = -1;
585 static int hf_gsm_a_rr_reporting_rate = -1;
586 static int hf_gsm_a_rr_invalid_bsic_reporting = -1;
587 static int hf_gsm_a_rr_scale_ord = -1;
588 static int hf_gsm_a_rr_900_reporting_offset = -1;
589 static int hf_gsm_a_rr_900_reporting_threshold = -1;
590 static int hf_gsm_a_rr_1800_reporting_offset = -1;
591 static int hf_gsm_a_rr_1800_reporting_threshold = -1;
592 static int hf_gsm_a_rr_400_reporting_offset = -1;
593 static int hf_gsm_a_rr_400_reporting_threshold = -1;
594 static int hf_gsm_a_rr_1900_reporting_offset = -1;
595 static int hf_gsm_a_rr_1900_reporting_threshold = -1;
596 static int hf_gsm_a_rr_850_reporting_offset = -1;
597 static int hf_gsm_a_rr_850_reporting_threshold = -1;
598 static int hf_gsm_a_rr_network_control_order = -1;
599 static int hf_gsm_a_rr_nc_non_drx_period = -1;
600 static int hf_gsm_a_rr_nc_reporting_period_i = -1;
601 static int hf_gsm_a_rr_nc_reporting_period_t = -1;
602 static int hf_gsm_a_rr_index_start_3g = -1;
603 static int hf_gsm_a_rr_absolute_index_start_emr = -1;
604 static int hf_gsm_a_rr_qsearch_c_initial = -1;
605 static int hf_gsm_a_rr_fdd_rep_quant = -1;
606 static int hf_gsm_a_rr_fdd_multirat_reporting = -1;
607 static int hf_gsm_a_rr_tdd_multirat_reporting = -1;
608 static int hf_gsm_a_rr_qsearch_p = -1;
609 static int hf_gsm_a_rr_3g_search_prio = -1;
610 static int hf_gsm_a_rr_fdd_reporting_offset = -1;
611 static int hf_gsm_a_rr_fdd_reporting_threshold = -1;
612 static int hf_gsm_a_rr_tdd_reporting_offset = -1;
613 static int hf_gsm_a_rr_tdd_reporting_threshold = -1;
614 static int hf_gsm_a_rr_fdd_reporting_threshold_2 = -1;
615 static int hf_gsm_a_rr_3g_ccn_active = -1;
616 static int hf_gsm_a_rr_700_reporting_offset = -1;
617 static int hf_gsm_a_rr_700_reporting_threshold = -1;
618 static int hf_gsm_a_rr_810_reporting_offset = -1;
619 static int hf_gsm_a_rr_810_reporting_threshold = -1;
620 static int hf_gsm_a_rr_cbq = -1;
621 static int hf_gsm_a_rr_cell_reselect_offset = -1;
622 static int hf_gsm_a_rr_temporary_offset = -1;
623 static int hf_gsm_a_rr_penalty_time = -1;
624 static int hf_gsm_a_rr_si13_position = -1;
625 static int hf_gsm_a_rr_power_offset = -1;
626 static int hf_gsm_a_rr_si2quater_position = -1;
627 static int hf_gsm_a_rr_si13alt_position = -1;
628 static int hf_gsm_a_rr_prio_thr = -1;
629 static int hf_gsm_a_rr_lsa_offset = -1;
630 static int hf_gsm_a_rr_paging_channel_restructuring = -1;
631 static int hf_gsm_a_rr_nln_sacch = -1;
632 static int hf_gsm_a_rr_nln_status_sacch = -1;
633 static int hf_gsm_a_rr_nln_pch = -1;
634 static int hf_gsm_a_rr_nln_status_pch = -1;
635 static int hf_gsm_a_rr_vbs_vgcs_inband_notifications = -1;
636 static int hf_gsm_a_rr_vbs_vgcs_inband_pagings = -1;
637 static int hf_gsm_a_rr_rac = -1;
638 static int hf_gsm_a_rr_max_lapdm = -1;
639 static int hf_gsm_a_rr_gprs_ms_txpwr_max_ccch = -1;
640 static int hf_gsm_a_rr_dedicated_mode_mbms_notification_support = -1;
641 static int hf_gsm_a_rr_mnci_support = -1;
642 static int hf_gsm_a_rr_amr_config = -1;
643 static int hf_gsm_a_rr_bcch_change_mark = -1;
644 static int hf_gsm_a_rr_si_change_field = -1;
645 static int hf_gsm_a_rr_si13_change_mark = -1;
646 static int hf_gsm_a_rr_hsn = -1;
647 static int hf_gsm_a_rr_rfl_number = -1;
648 static int hf_gsm_a_rr_arfcn_index = -1;
649 static int hf_gsm_a_rr_ma_length = -1;
650 static int hf_gsm_a_rr_psi1_repeat_period = -1;
651 static int hf_gsm_a_rr_pbcch_pb = -1;
652 static int hf_gsm_a_rr_pbcch_tsc = -1;
653 static int hf_gsm_a_rr_pbcch_tn = -1;
654 static int hf_gsm_a_rr_spgc_ccch_sup = -1;
655 static int hf_gsm_a_rr_priority_access_thr = -1;
656 static int hf_gsm_a_rr_nmo = -1;
657 static int hf_gsm_a_rr_t3168 = -1;
658 static int hf_gsm_a_rr_t3192 = -1;
659 static int hf_gsm_a_rr_drx_timer_max = -1;
660 static int hf_gsm_a_rr_access_burst_type = -1;
661 static int hf_gsm_a_rr_control_ack_type = -1;
662 static int hf_gsm_a_rr_bs_cv_max = -1;
663 static int hf_gsm_a_rr_pan_dec = -1;
664 static int hf_gsm_a_rr_pan_inc = -1;
665 static int hf_gsm_a_rr_pan_max = -1;
666 static int hf_gsm_a_rr_egprs_packet_channel_request = -1;
667 static int hf_gsm_a_rr_bep_period = -1;
668 static int hf_gsm_a_rr_pfc_feature_mode = -1;
669 static int hf_gsm_a_rr_dtm_support = -1;
670 static int hf_gsm_a_rr_bss_paging_coordination = -1;
671 static int hf_gsm_a_rr_ccn_active = -1;
672 static int hf_gsm_a_rr_nw_ext_utbf = -1;
673 static int hf_gsm_a_rr_multiple_tbf_capability = -1;
674 static int hf_gsm_a_rr_ext_utbf_no_data = -1;
675 static int hf_gsm_a_rr_dtm_enhancements_capability = -1;
676 static int hf_gsm_a_rr_reduced_latency_access = -1;
677 static int hf_gsm_a_rr_alpha = -1;
678 static int hf_gsm_a_rr_t_avg_w = -1;
679 static int hf_gsm_a_rr_t_avg_t = -1;
680 static int hf_gsm_a_rr_pc_meas_chan = -1;
681 static int hf_gsm_a_rr_n_avg_i = -1;
682 static int hf_gsm_a_rr_sgsnr = -1;
683 static int hf_gsm_a_rr_si_status_ind = -1;
684 static int hf_gsm_a_rr_lb_ms_txpwr_max_cch = -1;
685 static int hf_gsm_a_rr_si2n_support = -1;
686 static int hf_gsm_a_rr_mi_index = -1;
687 static int hf_gsm_a_rr_mi_count = -1;
688 static int hf_gsm_a_rr_3g_wait = -1;
689 static int hf_gsm_a_rr_qsearch_c = -1;
690 static int hf_gsm_a_rr_bsic_seen = -1;
691 static int hf_gsm_a_rr_scale = -1;
692 static int hf_gsm_a_rr_mean_bep_gmsk = -1;
693 static int hf_gsm_a_rr_mean_cv_bep = -1;
694 static int hf_gsm_a_rr_nbr_rcvd_blocks = -1;
695 static int hf_gsm_a_rr_reporting_quantity = -1;
696 /* Additions in Rel-8 */
697 static int hf_gsm_a_rr_3g_priority_param_desc_utran_start = -1;
698 static int hf_gsm_a_rr_3g_priority_param_desc_utran_stop = -1;
699 static int hf_gsm_a_rr_3g_priority_param_desc_default_utran_prio = -1;
700 static int hf_gsm_a_rr_3g_priority_param_desc_default_threshold_utran = -1;
701 static int hf_gsm_a_rr_3g_priority_param_desc_default_utran_qrxlevmin = -1;
702 static int hf_gsm_a_rr_utran_frequency_index = -1;
703 static int hf_gsm_a_rr_utran_priority = -1;
704 static int hf_gsm_a_rr_thresh_utran_high = -1;
705 static int hf_gsm_a_rr_thresh_utran_low = -1;
706 static int hf_gsm_a_rr_utran_qrxlevmin = -1;
707 static int hf_gsm_a_rr_eutran_ccn_active = -1;
708 static int hf_gsm_a_rr_eutran_start = -1;
709 static int hf_gsm_a_rr_eutran_stop = -1;
710 static int hf_gsm_a_rr_qsearch_c_eutran_initial = -1;
711 static int hf_gsm_a_rr_eutran_rep_quant = -1;
712 static int hf_gsm_a_rr_eutran_multirat_reporting = -1;
713 static int hf_gsm_a_rr_eutran_fdd_reporting_threshold = -1;
714 static int hf_gsm_a_rr_eutran_fdd_reporting_threshold_2 = -1;
715 static int hf_gsm_a_rr_eutran_tdd_reporting_threshold = -1;
716 static int hf_gsm_a_rr_eutran_tdd_reporting_threshold_2 = -1;
717 static int hf_gsm_a_rr_eutran_fdd_measurement_report_offset = -1;
718 static int hf_gsm_a_rr_eutran_tdd_measurement_report_offset = -1;
719 static int hf_gsm_a_rr_reporting_granularity = -1;
720 static int hf_gsm_a_rr_qsearch_p_eutran = -1;
721 static int hf_gsm_a_rr_serving_cell_priority_param_geran_priority = -1;
722 static int hf_gsm_a_rr_serving_cell_priority_param_threash_prio_search = -1;
723 static int hf_gsm_a_rr_serving_cell_priority_param_threash_gsm_low = -1;
724 static int hf_gsm_a_rr_serving_cell_priority_param_h_prio = -1;
725 static int hf_gsm_a_rr_serving_cell_priority_param_t_reselection = -1;
726 static int hf_gsm_a_rr_eutran_earfcn = -1;
727 static int hf_gsm_a_rr_eutran_measurement_bandwidth = -1;
728 static int hf_gsm_a_rr_eutran_priority = -1;
729 static int hf_gsm_a_rr_thresh_eutran_high = -1;
730 static int hf_gsm_a_rr_thresh_eutran_low = -1;
731 static int hf_gsm_a_rr_eutran_qrxlevmin = -1;
732 static int hf_gsm_a_rr_eutran_pcid = -1;
733 static int hf_gsm_a_rr_eutran_pcid_bitmap_group = -1;
734 static int hf_gsm_a_rr_eutran_pcid_pattern_length = -1;
735 static int hf_gsm_a_rr_eutran_pcid_pattern = -1;
736 static int hf_gsm_a_rr_eutran_pcid_pattern_sense = -1;
737 static int hf_gsm_a_rr_eutran_frequency_index = -1;
738 static int hf_gsm_a_rr_psc = -1;
739 static int hf_gsm_a_rr_utran_psc_pattern_length = -1;
740 static int hf_gsm_a_rr_utran_psc_pattern_sense = -1;
741 static int hf_gsm_a_rr_utran_csg_fdd_uarfcn = -1;
742 static int hf_gsm_a_rr_utran_csg_tdd_uarfcn = -1;
743 static int hf_gsm_a_rr_csg_earfcn = -1;
744
745 /* Initialize the subtree pointers */
746 static gint ett_ccch_msg = -1;
747 static gint ett_ccch_oct_1 = -1;
748 static gint ett_sacch_msg = -1;
749
750 static char a_bigbuf[1024];
751
752 static dissector_handle_t data_handle;
753 static dissector_handle_t rrlp_dissector;
754
755
756 #define NUM_GSM_RR_ELEM (sizeof(gsm_rr_elem_strings)/sizeof(value_string))
757 gint ett_gsm_rr_elem[NUM_GSM_RR_ELEM];
758
759 typedef enum
760 {
761     /* RR Rest Octets information elements */
762     DE_RR_REST_OCTETS_UTRAN_FDD_DESC,
763     DE_RR_REST_OCTETS_UTRAN_TDD_DESC,
764     DE_RR_REST_OCTETS_3G_MEAS_PARAM_DESC,
765     DE_RR_REST_OCTETS_3G_ADD_MEAS_PARAM_DESC,
766     DE_RR_REST_OCTETS_MEAS_PARAM_DESC,
767     DE_RR_REST_OCTETS_GPRS_RTD_DESC,
768     DE_RR_REST_OCTETS_GPRS_BSIC_DESC,
769     DE_RR_REST_OCTETS_GPRS_REPORT_PRIO_DESC,
770     DE_RR_REST_OCTETS_GPRS_MEAS_PARAM_DESC,
771     DE_RR_REST_OCTETS_NC_MEAS_PARAM,
772     DE_RR_REST_OCTETS_SI2Q_EXT_INFO,
773     DE_RR_REST_OCTETS_CCN_SUPPORT_DESC,
774     DE_RR_REST_OCTETS_3G_NEIGH_CELL_DESC,
775     DE_RR_REST_OCTETS_FDD_CELL_INFORMATION_FIELD,
776     DE_RR_REST_OCTETS_TDD_CELL_INFORMATION_FIELD,
777     DE_RR_REST_OCTETS_GPRS_3G_MEAS_PARAM_DESC,
778     DE_RR_REST_OCTETS_3G_ADD_MEAS_PARAM_DESC2,
779     DE_RR_REST_OCTETS_PRIORITY_AND_EUTRAN_PARAM_DESC,
780     DE_RR_REST_OCTETS_3G_PRIORITY_PARAM_DESC,
781     DE_RR_REST_OCTETS_EUTRAN_PARAM_DESC,
782     DE_RR_REST_OCTETS_EUTRAN_NEIGHBOUR_CELLS,
783     DE_RR_REST_OCTETS_EUTRAN_NOT_ALLOWED_CELLS,
784     DE_RR_REST_OCTETS_EUTRAN_PCID_TO_TA_MAPPING,
785     DE_RR_REST_OCTETS_3G_CSG_DESC,
786     DE_RR_REST_OCTETS_EUTRAN_CSG_DESC,
787     DE_RR_REST_OCTETS_OPTIONAL_SEL_PARAM,
788     DE_RR_REST_OCTETS_GPRS_INDICATOR,
789     DE_RR_REST_OCTETS_SI4_REST_OCTETS_O,
790     DE_RR_REST_OCTETS_SI4_REST_OCTETS_S,
791     DE_RR_REST_OCTETS_LSA_PARAMETERS,
792     DE_RR_REST_OCTETS_LSA_ID_INFO,
793     DE_RR_REST_OCTETS_PCH_AND_NCH_INFO,
794     DE_RR_REST_OCTETS_VBS_VGCS_OPTIONS,
795     DE_RR_REST_OCTETS_GPRS_MOBILE_ALLOC,
796     DE_RR_REST_OCTETS_GPRS_CELL_OPTIONS,
797     DE_RR_REST_OCTETS_GPRS_CELL_OPTIONS_EXT_INFO,
798     DE_RR_REST_OCTETS_GPRS_POWER_CONTROL_PARAMS,
799     DE_RR_REST_OCTETS_PBCCH_DESC,
800     DE_RR_REST_OCTETS_GSM_DESC,
801     DE_RR_REST_OCTETS_RTD_DESC,
802     DE_RR_REST_OCTETS_BSIC_DESC,
803     DE_RR_REST_OCTETS_REPORT_PRIO_DESC,
804     DE_RR_REST_OCTETS_CDMA2000_DESC,
805     DE_RR_REST_OCTETS_SERVING_CELL_DATA,
806     DE_RR_REST_OCTETS_REPEAT_INV_BSIC_INFO,
807     DE_RR_REST_OCTETS_BITMAP_TYPE_REPORTING,
808     DE_RR_REST_OCTETS_NONE
809 }
810 rr_rest_octets_elem_idx_t;
811
812 #define NUM_GSM_RR_REST_OCTETS_ELEM (sizeof(gsm_rr_rest_octets_elem_strings)/sizeof(value_string))
813 gint ett_gsm_rr_rest_octets_elem[NUM_GSM_RR_REST_OCTETS_ELEM];
814
815 /*
816 10.5.2 Radio Resource management information elements
817  * [3] 10.5.2.1a BA Range
818  */
819 guint16
820 de_rr_ba_range(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
821 {
822     guint32 curr_offset;
823     gint bit_offset;
824     guint8 value;
825
826     curr_offset = offset;
827     proto_tree_add_item(tree, hf_gsm_a_rr_range_nb, tvb, curr_offset, 1, FALSE);
828     value = tvb_get_guint8(tvb, curr_offset);
829     curr_offset += 1;
830     bit_offset = curr_offset << 3;
831     while (value)
832     {
833         proto_tree_add_bits_item(tree, hf_gsm_a_rr_range_lower, tvb, bit_offset, 10, FALSE);
834         bit_offset += 10;
835         proto_tree_add_bits_item(tree, hf_gsm_a_rr_range_higher, tvb, bit_offset, 10, FALSE);
836         bit_offset += 10;
837         value -= 1;
838     }
839
840     curr_offset += len - 1;
841     return (curr_offset - offset);
842 }
843
844 /*
845  * [3] 10.5.2.1b Cell Channel Description
846  */
847
848 #define ARFCN_MAX 1024 /* total number of ARFCNs defined */
849
850 static void display_channel_list(guint8 *list, tvbuff_t *tvb, proto_tree *tree, guint32 offset)
851 {
852     int arfcn;
853     proto_item *ti=NULL;
854
855     ti = proto_tree_add_text(tree, tvb, 0, offset, "List of ARFCNs =");
856     for (arfcn=0; arfcn<ARFCN_MAX; arfcn++) {
857         if (list[arfcn])
858             proto_item_append_text(ti, " %d", arfcn);
859     }
860
861     return;
862 }
863
864 static gint greatest_power_of_2_lesser_or_equal_to(gint idx)
865 {
866     gint j = 1;
867     do {
868         j<<=1;
869     } while (j<=idx);
870     j >>= 1;
871     return j;
872 }
873
874 static gint f_k(gint k, gint *w, gint range)
875 {
876     gint idx, n, j;
877
878     idx = k;
879     range -= 1;
880     range = range/greatest_power_of_2_lesser_or_equal_to(idx);
881     n = w[idx]-1;
882
883     while (idx>1) {
884         j = greatest_power_of_2_lesser_or_equal_to(idx);
885         range = 2*range+1;
886         if ((2*idx) < 3*j){ /* left child */
887             idx -= j/2;
888             n = (n+w[idx]-1+((range-1)/2)+1)%range;
889         }
890         else { /* right child */
891             idx -= j;
892             n = (n+w[idx]-1+1)%range;
893         }
894     }
895
896     return (n+1)%1024;
897 }
898
899 static void dissect_channel_list_n_range(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gint range)
900 {
901     gint curr_offset=offset, f0, arfcn_orig, bits, w[64], wsize, i, wi;
902     gint octet, nwi=1, jwi=0, wbits, imax, iused, arfcn;
903     guint8 list[1024];
904
905     memset((void*)list,0,sizeof(list));
906
907     octet = tvb_get_guint8(tvb, curr_offset++);
908     if (range==1024) {
909         f0 = (octet>>2)&1;
910         if (f0)
911             list[0] = 1;
912         bits = 2;
913         arfcn_orig = 0;
914         wsize = 10;
915         imax = 16;
916     }
917     else {
918         arfcn_orig = (octet&1);
919         arfcn_orig = (arfcn_orig << 8) + tvb_get_guint8(tvb, curr_offset++);
920         octet = tvb_get_guint8(tvb, curr_offset++);
921         arfcn_orig = (arfcn_orig << 1) + (octet>>7);
922         list[arfcn_orig] = 1;
923         bits = 7;
924         switch (range) {
925         case 512:
926             wsize=9;
927             imax = 17;
928             break;
929         case 256:
930             wsize=8;
931             imax = 21;
932             break;
933         case 128:
934             wsize=7;
935             imax = 28;
936             break;
937         default:
938             wsize=0;
939             imax = 0;
940             DISSECTOR_ASSERT_NOT_REACHED();
941         }
942     }
943     iused = imax;   /* in case the list is actually full */
944
945     /* extract the variable size w[] elements */
946     for (i=1; i<=imax; i++) {
947         wi = octet & ~(0xff<<bits);      /* mask "bits" low bits to start wi from existing octet */
948         wbits = bits;
949         while (wsize>wbits) {        /* need to extract more bits from the next octet */
950             octet = tvb_get_guint8(tvb, curr_offset++);
951             wi = (wi << 8) + octet;
952             bits = 8;
953             wbits += 8;
954         }
955
956         if (wbits>wsize) {      /* now we have too many bits - save some */
957             bits = wbits - wsize;
958             wi >>= bits;
959         }
960         else                    /* just right number of bits */
961             bits = 0;
962
963         w[i] = wi;
964         if ((w[i]==0) || ((curr_offset-offset)>len)) {
965             iused = i - 1;
966             break;        /* all remaining elements must also be zero */
967         }
968
969         if (++jwi==nwi) {       /* check if the number of wi at this wsize has been extracted */
970             jwi = 0;            /* reset the count of wi at this size */
971             nwi <<= 1;          /* get twice as many of the next size */
972             wsize--;            /* make the next size 1 bit smaller */
973         }
974     }
975
976     for (i=1; i<=iused; i++) {
977         arfcn = (f_k(i, w, range) + arfcn_orig)%1024;
978         list[arfcn] = 1;
979     }
980
981     display_channel_list(list, tvb, tree, offset);
982
983     return;
984 }
985
986 static guint16
987 dissect_arfcn_list_core(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_, guint8 format)
988 {
989     guint32 curr_offset,byte;
990     guint8  oct,bit;
991     guint16 arfcn;
992     proto_item  *item;
993
994     curr_offset = offset;
995
996     if ((format & 0xc0) == 0x00)
997     {
998         /* bit map 0 */
999         item = proto_tree_add_text(tree,tvb, curr_offset, len, "List of ARFCNs =");
1000         bit = 4;
1001         arfcn = 125;
1002         for (byte = 0;byte <= len-1;byte++)
1003         {
1004             oct = tvb_get_guint8(tvb, curr_offset);
1005             while (bit-- != 0)
1006             {
1007                 arfcn--;
1008                 if (((oct >> bit) & 1) == 1)
1009                 {
1010                     proto_item_append_text(item," %d",arfcn);
1011                 }
1012             }
1013             bit = 8;
1014             curr_offset++;
1015         }
1016     }
1017     else if ((format & 0xc8) == 0x80)
1018     {
1019         /* 1024 range */
1020         dissect_channel_list_n_range(tvb, tree, curr_offset, len, 1024);
1021         curr_offset = curr_offset + len;
1022     }
1023     else if ((format & 0xce) == 0x88)
1024     {
1025         /* 512 range */
1026         dissect_channel_list_n_range(tvb, tree, curr_offset, len, 512);
1027         curr_offset = curr_offset + len;
1028     }
1029     else if ((format & 0xce) == 0x8a)
1030     {
1031         /* 256 range */
1032         dissect_channel_list_n_range(tvb, tree, curr_offset, len, 256);
1033         curr_offset = curr_offset + len;
1034     }
1035     else if ((format & 0xce) == 0x8c)
1036     {
1037         /* 128 range */
1038         dissect_channel_list_n_range(tvb, tree, curr_offset, len, 128);
1039         curr_offset = curr_offset + len;
1040     }
1041     else if ((format & 0xce) == 0x8e)
1042     {
1043         /* variable bit map */
1044         arfcn = ((format & 0x01) << 9) | (tvb_get_guint8(tvb, curr_offset+1) << 1) | ((tvb_get_guint8(tvb, curr_offset + 2) & 0x80) >> 7);
1045         item = proto_tree_add_text(tree,tvb,curr_offset,len,"List of ARFCNs = %d",arfcn);
1046         curr_offset = curr_offset + 2;
1047         bit = 7;
1048         for (byte = 0;byte <= len-3;byte++)
1049         {
1050             oct = tvb_get_guint8(tvb, curr_offset);
1051             while (bit-- != 0)
1052             {
1053                 arfcn++;
1054                 if (((oct >> bit) & 1) == 1)
1055                 {
1056                     proto_item_append_text(item," %d",arfcn);
1057                 }
1058             }
1059             bit = 8;
1060             curr_offset++;
1061         }
1062     }
1063
1064     return(curr_offset - offset);
1065 }
1066
1067 /*
1068  * Format ID is in bits:
1069  * 128 127 124 123 122 (hf_gsm_a_rr_format_id)
1070  */
1071 static guint16
1072 dissect_arfcn_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
1073 {
1074     guint32     curr_offset;
1075     guint8  oct;
1076
1077     curr_offset = offset;
1078
1079     oct = tvb_get_guint8(tvb, curr_offset);
1080
1081     /* FORMAT-ID, Format Identifier (part of octet 3)*/
1082     proto_tree_add_item(tree, hf_gsm_a_rr_format_id, tvb, curr_offset, 1, FALSE);
1083
1084     curr_offset += dissect_arfcn_list_core(tvb, tree, offset, len, add_string, string_len, oct);
1085
1086     return(curr_offset - offset);
1087 }
1088
1089 /*
1090  * Format ID is in bits:
1091  * 128 124 123 122 (hf_gsm_a_rr_format_id2)
1092  */
1093 static guint16
1094 dissect_arfcn_list2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
1095 {
1096     guint32     curr_offset;
1097     guint8  oct;
1098
1099     curr_offset = offset;
1100
1101     /* Turn bit 127 off, in order to reuse the ARFCN dissection code */
1102     oct = tvb_get_guint8(tvb, curr_offset) & 0xbf;
1103
1104     /* FORMAT-ID, Format Identifier (part of octet 3)*/
1105     proto_tree_add_item(tree, hf_gsm_a_rr_format_id2, tvb, curr_offset, 1, FALSE);
1106
1107     curr_offset += dissect_arfcn_list_core(tvb, tree, offset, len, add_string, string_len, oct);
1108
1109     return(curr_offset - offset);
1110 }
1111
1112 guint16
1113 de_rr_cell_ch_dsc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
1114 {
1115     return dissect_arfcn_list(tvb, tree, offset, 16, add_string, string_len);
1116 }
1117 /*
1118  * [3] 10.5.2.1c BA List Pref
1119  */
1120 guint16
1121 de_rr_ba_list_pref(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
1122 {
1123     guint32 curr_offset;
1124     gint bit_offset;
1125     guint8 value;
1126
1127     curr_offset = offset;
1128     proto_tree_add_item(tree, hf_gsm_a_rr_ba_list_pref_length, tvb, curr_offset, 1, FALSE);
1129     bit_offset = curr_offset << 3;
1130     value = tvb_get_bits8(tvb,bit_offset,1);
1131     bit_offset += 1;
1132     while (value)
1133     {
1134         proto_tree_add_bits_item(tree, hf_gsm_a_rr_range_lower, tvb, bit_offset, 10, FALSE);
1135         bit_offset += 10;
1136         proto_tree_add_bits_item(tree, hf_gsm_a_rr_range_higher, tvb, bit_offset, 10, FALSE);
1137         bit_offset += 10;
1138         value = tvb_get_bits8(tvb,bit_offset,1);
1139         bit_offset += 1;
1140     }
1141     value = tvb_get_bits8(tvb,bit_offset,1);
1142     bit_offset += 1;
1143     while (value)
1144     {
1145         proto_tree_add_bits_item(tree, hf_gsm_a_rr_ba_freq, tvb, bit_offset, 10, FALSE);
1146         bit_offset += 10;
1147         value = tvb_get_bits8(tvb,bit_offset,1);
1148         bit_offset += 1;
1149     }
1150
1151     curr_offset += len;
1152     return (curr_offset - offset);
1153 }
1154
1155 /*
1156  * [3] 10.5.2.1d UTRAN Frequency List
1157  */
1158 guint16
1159 de_rr_utran_freq_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
1160 {
1161     guint32 curr_offset;
1162     gint bit_offset;
1163     guint8 value;
1164
1165     curr_offset = offset;
1166     proto_tree_add_item(tree, hf_gsm_a_rr_utran_freq_list_length, tvb, curr_offset, 1, FALSE);
1167     bit_offset = curr_offset << 3;
1168     value = tvb_get_bits8(tvb,bit_offset,1);
1169     bit_offset += 1;
1170     while (value)
1171     {
1172         proto_tree_add_bits_item(tree, hf_gsm_a_rr_fdd_uarfcn, tvb, bit_offset, 14, FALSE);
1173         bit_offset += 14;
1174         value = tvb_get_bits8(tvb,bit_offset,1);
1175         bit_offset += 1;
1176     }
1177     value = tvb_get_bits8(tvb,bit_offset,1);
1178     bit_offset += 1;
1179     while (value)
1180     {
1181         proto_tree_add_bits_item(tree, hf_gsm_a_rr_tdd_uarfcn, tvb, bit_offset, 14, FALSE);
1182         bit_offset += 14;
1183         value = tvb_get_bits8(tvb,bit_offset,1);
1184         bit_offset += 1;
1185     }
1186
1187     curr_offset += len;
1188     return (curr_offset - offset);
1189 }
1190
1191 /*
1192  * [3] 10.5.2.1e Cell selection indicator after release of all TCH and SDCCH
1193  */
1194 static const guint8
1195 convert_n_to_p[32] = {   0, 10, 19, 28, 26, 44, 52, 60, 67, 74, 81, 88, 95, 102, 109, 116,
1196                        122,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,   0,   0};
1197
1198 static const guint8
1199 convert_n_to_q[32] = {   0,   9,  17,  25,  32, 39, 46, 53, 59, 65, 71, 77, 83, 89, 95, 101,
1200                        106, 111, 116, 121, 126,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0};
1201
1202 guint16
1203 de_rr_cell_select_indic(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
1204 {
1205     proto_tree *subtree, *subtree2;
1206     proto_item *item, *item2;
1207     guint32 curr_offset;
1208     gint bit_offset, bit_offset_sav, idx, xdd_cell_info, wsize, nwi, jwi, w[64], i, iused, xdd_indic0;
1209     guint8 value, length;
1210
1211     curr_offset = offset;
1212     length = tvb_get_guint8(tvb, curr_offset);
1213     curr_offset += 1;
1214     bit_offset = curr_offset << 3;
1215     value = tvb_get_bits8(tvb,bit_offset,3);
1216     bit_offset += 3;
1217     switch (value)
1218     {
1219     case 0: /* GSM Description */
1220         bit_offset_sav = bit_offset;
1221         item = proto_tree_add_text(tree, tvb, bit_offset>>3, -1, "%s",
1222                                    gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_GSM_DESC].strptr);
1223         subtree = proto_item_add_subtree(item, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_GSM_DESC]);
1224         value = tvb_get_bits8(tvb,bit_offset,1);
1225         bit_offset += 1;
1226         while (value)
1227         {
1228             proto_tree_add_text(subtree,tvb, bit_offset>>3, 1, "Band Indicator: %s",tvb_get_bits8(tvb,bit_offset,1) ? "1900" : "1800");
1229             bit_offset += 1;
1230             proto_tree_add_bits_item(subtree, hf_gsm_a_rr_arfcn, tvb, bit_offset, 10, FALSE);
1231             bit_offset += 10;
1232             proto_tree_add_bits_item(subtree, hf_gsm_a_rr_bsic, tvb, bit_offset, 6, FALSE);
1233             bit_offset += 6;
1234             value = tvb_get_bits8(tvb,bit_offset,1);
1235             bit_offset += 1;
1236         }
1237         proto_item_set_len(item,((bit_offset-bit_offset_sav)>>3)+1);
1238         break;
1239     case 1: /* UTRAN FDD Description */
1240         bit_offset_sav = bit_offset;
1241         item = proto_tree_add_text(tree, tvb, bit_offset>>3, -1, "%s",
1242                                    gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_UTRAN_FDD_DESC].strptr);
1243         subtree = proto_item_add_subtree(item, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_UTRAN_FDD_DESC]);
1244         value = tvb_get_bits8(tvb,bit_offset,1);
1245         bit_offset += 1;
1246         while (value)
1247         {
1248             if (tvb_get_bits8(tvb,bit_offset,1))
1249             {
1250                 bit_offset += 1;
1251                 proto_tree_add_bits_item(subtree, hf_gsm_a_rr_bandwidth_fdd, tvb, bit_offset, 3, FALSE);
1252                 bit_offset += 3;
1253             }
1254             else
1255                 bit_offset += 1;
1256             proto_tree_add_bits_item(subtree, hf_gsm_a_rr_fdd_uarfcn, tvb, bit_offset, 14, FALSE);
1257             bit_offset += 14;
1258             if (tvb_get_bits8(tvb,bit_offset,1))
1259             {
1260                 bit_offset += 1;
1261                 xdd_indic0 = tvb_get_bits8(tvb,bit_offset,1);
1262                 proto_tree_add_text(subtree,tvb, bit_offset>>3, 1, "FDD Indic0: %d", xdd_indic0);
1263                 bit_offset += 1;
1264                 idx = tvb_get_bits8(tvb,bit_offset,5);
1265                 proto_tree_add_text(subtree,tvb, bit_offset>>3, 1, "Nr of FDD Cells : %d", idx);
1266                 bit_offset += 5;
1267                 idx = convert_n_to_p[idx];
1268                 item2 = proto_tree_add_text(subtree,tvb, bit_offset>>3, (idx>>3)+1, "%s",
1269                                             gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_UTRAN_FDD_DESC].strptr);
1270                 subtree2 = proto_item_add_subtree(item2, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_FDD_CELL_INFORMATION_FIELD]);
1271                 proto_tree_add_text(subtree2,tvb, bit_offset>>3, (idx>>3)+1, "Field is %d bits long", idx);
1272                 if (xdd_indic0)
1273                 {
1274                     proto_tree_add_text(subtree2,tvb, bit_offset>>3, 0, "Scrambling Code: %d", 0);
1275                     proto_tree_add_text(subtree2,tvb, bit_offset>>3, 0, "Diversity: %d", 0);
1276                 }
1277                 if (idx)
1278                 {
1279                     wsize = 10;
1280                     nwi = 1;
1281                     jwi = 0;
1282                     i = 1;
1283
1284                     while (idx > 0)
1285                     {
1286                         w[i] = tvb_get_bits(tvb, bit_offset, wsize, FALSE);
1287                         bit_offset += wsize;
1288                         idx -= wsize;
1289                         if (w[i] == 0)
1290                         {
1291                             idx = 0;
1292                             break;
1293                         }
1294                         if (++jwi==nwi)
1295                         {
1296                             jwi = 0;
1297                             nwi <<= 1;
1298                             wsize--;
1299                         }
1300                         i++;
1301                     }
1302                     if (idx < 0)
1303                     {
1304                         bit_offset += idx;
1305                     }
1306                     iused = i-1;
1307
1308                     for (i=1; i <= iused; i++)
1309                     {
1310                         xdd_cell_info = f_k(i, w, 1024);
1311                         proto_tree_add_text(subtree2,tvb, bit_offset>>3, 0,
1312                                             "Scrambling Code: %d", xdd_cell_info & 0x01FF);
1313                         proto_tree_add_text(subtree2,tvb, bit_offset>>3, 0,
1314                                             "Diversity: %d", (xdd_cell_info >> 9) & 0x01);
1315                     }
1316                 }
1317             }
1318             else
1319                 bit_offset += 1;
1320             value = tvb_get_bits8(tvb,bit_offset,1);
1321             bit_offset += 1;
1322         }
1323         proto_item_set_len(item,((bit_offset-bit_offset_sav)>>3)+1);
1324         break;
1325     case 2: /* UTRAN TDD Description */
1326         bit_offset_sav = bit_offset;
1327         item = proto_tree_add_text(tree, tvb, bit_offset>>3, -1, "%s", gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_UTRAN_TDD_DESC].strptr);
1328         subtree = proto_item_add_subtree(item, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_UTRAN_TDD_DESC]);
1329         value = tvb_get_bits8(tvb,bit_offset,1);
1330         bit_offset += 1;
1331         while (value)
1332         {
1333             if (tvb_get_bits8(tvb,bit_offset,1))
1334             {
1335                 bit_offset += 1;
1336                 proto_tree_add_bits_item(subtree, hf_gsm_a_rr_bandwidth_tdd, tvb, bit_offset, 3, FALSE);
1337                 bit_offset += 3;
1338             }
1339             else
1340                 bit_offset += 1;
1341             proto_tree_add_bits_item(subtree, hf_gsm_a_rr_tdd_uarfcn, tvb, bit_offset, 14, FALSE);
1342             bit_offset += 14;
1343             if (tvb_get_bits8(tvb,bit_offset,1))
1344             {
1345                 bit_offset += 1;
1346                 xdd_indic0 = tvb_get_bits8(tvb,bit_offset,1);
1347                 proto_tree_add_text(subtree,tvb, bit_offset>>3, 1, "TDD Indic0: %d", xdd_indic0);
1348                 bit_offset += 1;
1349                 idx = tvb_get_bits8(tvb,bit_offset,5);
1350                 proto_tree_add_text(subtree,tvb, bit_offset>>3, 1, "Nr of TDD Cells : %d", idx);
1351                 bit_offset += 5;
1352                 idx = convert_n_to_q[idx];
1353                 item2 = proto_tree_add_text(subtree,tvb, bit_offset>>3, (idx>>3)+1, "%s",
1354                                             gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_UTRAN_TDD_DESC].strptr);
1355                 subtree2 = proto_item_add_subtree(item2, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_TDD_CELL_INFORMATION_FIELD]);
1356                 proto_tree_add_text(subtree2,tvb, bit_offset>>3, (idx>>3)+1, "Field is %d bits long", idx);
1357                 if (xdd_indic0)
1358                 {
1359                     proto_tree_add_text(subtree2,tvb, bit_offset>>3, 0, "Cell Parameter: %d", 0);
1360                     proto_tree_add_text(subtree2,tvb, bit_offset>>3, 0, "Sync Case TSTD: %d", 0);
1361                     proto_tree_add_text(subtree2,tvb, bit_offset>>3, 0, "Diversity TDD: %d", 0);
1362                 }
1363                 if (idx)
1364                 {
1365                     wsize = 9;
1366                     nwi = 1;
1367                     jwi = 0;
1368                     i = 1;
1369
1370                     while (idx > 0)
1371                     {
1372                         w[i] = tvb_get_bits(tvb, bit_offset, wsize, FALSE);
1373                         bit_offset += wsize;
1374                         idx -= wsize;
1375                         if (w[i] == 0)
1376                         {
1377                             idx = 0;
1378                             break;
1379                         }
1380                         if (++jwi==nwi)
1381                         {
1382                             jwi = 0;
1383                             nwi <<= 1;
1384                             wsize--;
1385                         }
1386                         i++;
1387                     }
1388                     if (idx < 0)
1389                     {
1390                         bit_offset += idx;
1391                     }
1392                     iused = i-1;
1393
1394                     for (i=1; i <= iused; i++)
1395                     {
1396                         xdd_cell_info = f_k(i, w, 512);
1397                         proto_tree_add_text(subtree2,tvb, bit_offset>>3, 0,
1398                                             "Cell Parameter: %d", xdd_cell_info & 0x07F);
1399                         proto_tree_add_text(subtree2,tvb, bit_offset>>3, 0,
1400                                             "Sync Case TSTD: %d", (xdd_cell_info >> 7) & 0x01);
1401                         proto_tree_add_text(subtree2,tvb, bit_offset>>3, 0,
1402                                             "Diversity TDD: %d", (xdd_cell_info >> 8) & 0x01);
1403                     }
1404                 }
1405             }
1406             else
1407                 bit_offset += 1;
1408             value = tvb_get_bits8(tvb,bit_offset,1);
1409             bit_offset += 1;
1410         }
1411         proto_item_set_len(item,((bit_offset-bit_offset_sav)>>3)+1);
1412         break;
1413     default:
1414         break;
1415     }
1416
1417     curr_offset += length;
1418     return (curr_offset - offset);
1419 }
1420
1421 /*
1422  * [3] 10.5.2.2 Cell Description
1423  */
1424 guint16
1425 de_rr_cell_dsc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
1426 {
1427     proto_tree  *subtree;
1428     proto_item  *item;
1429     guint8      oct;
1430     guint32     curr_offset;
1431     guint16 bcch_arfcn;
1432
1433     curr_offset = offset;
1434
1435     oct = tvb_get_guint8(tvb, curr_offset);
1436     item =
1437         proto_tree_add_text(tree,
1438                             tvb, curr_offset, 2, "%s",
1439                             gsm_rr_elem_strings[DE_RR_CELL_DSC].strptr);
1440
1441     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_CELL_DSC]);
1442
1443     proto_tree_add_item(subtree, hf_gsm_a_ncc, tvb, curr_offset, 1, FALSE);
1444     proto_tree_add_item(subtree, hf_gsm_a_bcc, tvb, curr_offset, 1, FALSE);
1445     bcch_arfcn = (tvb_get_guint8(tvb,curr_offset) & 0xc0) << 2;
1446     bcch_arfcn = bcch_arfcn | tvb_get_guint8(tvb,curr_offset+1);
1447     proto_tree_add_uint(subtree, hf_gsm_a_bcch_arfcn , tvb, curr_offset, 2, bcch_arfcn );
1448
1449     curr_offset = curr_offset + 2;
1450
1451     return(curr_offset - offset);
1452 }
1453
1454 /*
1455  * [3] 10.5.2.3 Cell Options (BCCH)
1456  */
1457 static const value_string gsm_a_rr_dtx_bcch_vals[] = {
1458     { 0x00, "The MSs may use uplink discontinuous transmission" },
1459     { 0x01, "The MSs shall use uplink discontinuous transmission" },
1460     { 0x02, "The MSs shall not use uplink discontinuous transmission" },
1461     { 0x03, "Reserved" },
1462     {    0, NULL } };
1463
1464 static const value_string gsm_a_rr_radio_link_timeout_vals[] = {
1465     { 0x00, "4" },
1466     { 0x01, "8" },
1467     { 0x02, "12" },
1468     { 0x03, "16" },
1469     { 0x04, "20" },
1470     { 0x05, "24" },
1471     { 0x06, "28" },
1472     { 0x07, "32" },
1473     { 0x08, "36" },
1474     { 0x09, "40" },
1475     { 0x0A, "44" },
1476     { 0x0B, "48" },
1477     { 0x0C, "52" },
1478     { 0x0D, "56" },
1479     { 0x0E, "60" },
1480     { 0x0F, "64" },
1481     {    0, NULL } };
1482
1483 static guint16
1484 de_rr_cell_opt_bcch(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
1485 {
1486     proto_tree  *subtree;
1487     proto_item  *item;
1488     guint32     curr_offset;
1489
1490     curr_offset = offset;
1491
1492     item = proto_tree_add_text(tree, tvb, curr_offset, 1, "%s",
1493                                gsm_rr_elem_strings[DE_RR_CELL_OPT_BCCH].strptr);
1494
1495     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_CELL_OPT_BCCH]);
1496
1497     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_pwrc, tvb, (curr_offset<<3)+1, 1, FALSE);
1498     proto_tree_add_item(subtree, hf_gsm_a_rr_dtx_bcch, tvb, curr_offset, 1, FALSE);
1499     proto_tree_add_item(subtree, hf_gsm_a_rr_radio_link_timeout, tvb, curr_offset, 1, FALSE);
1500
1501     curr_offset = curr_offset + 1;
1502
1503     return(curr_offset - offset);
1504 }
1505
1506 /*
1507  * [3] 10.5.2.3a Cell Options (SACCH)
1508  */
1509 static const value_string gsm_a_rr_dtx_sacch_vals[] = {
1510     { 0x00, "The MS may use uplink discontinuous transmission on a TCH-F. The MS shall not use uplink discontinuous transmission on TCH-H" },
1511     { 0x01, "The MS shall use uplink discontinuous transmission on a TCH-F. The MS shall not use uplink discontinuous transmission on TCH-H" },
1512     { 0x02, "The MS shall not use uplink discontinuous transmission on a TCH-F. The MS shall not use uplink discontinuous transmission on TCH-H" },
1513     { 0x03, "The MS shall use uplink discontinuous transmission on a TCH-F. The MS may use uplink discontinuous transmission on TCH-H" },
1514     { 0x04, "The MS may use uplink discontinuous transmission on a TCH-F. The MS may use uplink discontinuous transmission on TCH-H" },
1515     { 0x05, "The MS shall use uplink discontinuous transmission on a TCH-F. The MS shall use uplink discontinuous transmission on TCH-H" },
1516     { 0x06, "The MS shall not use uplink discontinuous transmission on a TCH-F. The MS shall use uplink discontinuous transmission on TCH-H" },
1517     { 0x07, "The MS may use uplink discontinuous transmission on a TCH-F. The MS shall use uplink discontinuous transmission on TCH-H" },
1518     {    0, NULL } };
1519
1520 static guint16
1521 de_rr_cell_opt_sacch(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
1522 {
1523     proto_tree  *subtree;
1524     proto_item  *item;
1525     guint8      oct;
1526     guint8      dtx;
1527     guint32     curr_offset;
1528
1529     curr_offset = offset;
1530
1531     oct = tvb_get_guint8(tvb, curr_offset);
1532     dtx = ((oct&0x80)>>5)|((oct&0x30)>>4); /* DTX is a split filed in bits 8, 6 and 5 */
1533     item = proto_tree_add_text(tree, tvb, curr_offset, 1, "%s",
1534                                gsm_rr_elem_strings[DE_RR_CELL_OPT_SACCH].strptr);
1535
1536     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_CELL_OPT_SACCH]);
1537
1538     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_pwrc, tvb, (curr_offset<<3)+1, 1, FALSE);
1539     proto_tree_add_uint(subtree, hf_gsm_a_rr_dtx_sacch, tvb, curr_offset, 1, dtx);
1540     proto_tree_add_item(subtree, hf_gsm_a_rr_radio_link_timeout, tvb, curr_offset, 1, FALSE);
1541
1542     curr_offset = curr_offset + 1;
1543
1544     return(curr_offset - offset);
1545 }
1546
1547 /*
1548  * [3] 10.5.2.4 Cell Selection Parameters
1549  */
1550 static guint16
1551 de_rr_cell_sel_param(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
1552 {
1553     proto_tree  *subtree;
1554     proto_item  *item;
1555     guint8      oct;
1556     guint32     curr_offset;
1557
1558     curr_offset = offset;
1559
1560     oct = tvb_get_guint8(tvb, curr_offset);
1561     item = proto_tree_add_text(tree, tvb, curr_offset, 2, "%s",
1562                                gsm_rr_elem_strings[DE_RR_CELL_SEL_PARAM].strptr);
1563
1564     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_CELL_SEL_PARAM]);
1565
1566     proto_tree_add_item(subtree, hf_gsm_a_rr_cell_reselect_hyst, tvb, curr_offset, 1, FALSE);
1567     proto_tree_add_item(subtree, hf_gsm_a_rr_ms_txpwr_max_cch, tvb, curr_offset, 1, FALSE);
1568
1569     curr_offset = curr_offset + 1;
1570
1571     proto_tree_add_item(subtree, hf_gsm_a_rr_acs, tvb, curr_offset, 1, FALSE);
1572     proto_tree_add_item(subtree, hf_gsm_a_rr_neci, tvb, curr_offset, 1, FALSE);
1573     proto_tree_add_item(subtree, hf_gsm_a_rr_rxlev_access_min, tvb, curr_offset, 1, FALSE);
1574
1575     curr_offset = curr_offset + 1;
1576
1577     return(curr_offset - offset);
1578 }
1579
1580 /*
1581  * [3] 10.5.2.4a MAC Mode and Channel Coding Requested
1582  * [3] 10.5.2.5 Channel Description
1583  */
1584 guint16
1585 de_rr_ch_dsc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
1586 {
1587     guint32     curr_offset;
1588     guint8      oct8,subchannel;
1589     guint16 arfcn, hsn, maio;
1590     proto_tree  *subtree;
1591     proto_item  *item;
1592     const gchar *str;
1593
1594     curr_offset = offset;
1595
1596     item = proto_tree_add_text(tree,tvb, curr_offset, 3, "%s", gsm_rr_elem_strings[DE_RR_CH_DSC].strptr);
1597
1598     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_CH_DSC]);
1599
1600     /* Octet 2 */
1601     oct8 = tvb_get_guint8(tvb, curr_offset);
1602
1603     if ((oct8 & 0xf8) == 0x08)
1604     {
1605         str = "TCH/F + ACCHs";
1606         other_decode_bitfield_value(a_bigbuf, oct8, 0xf8, 8);
1607         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s",a_bigbuf,str);
1608     }
1609     else
1610     {
1611         if ((oct8 & 0xf0) == 0x10)
1612         {
1613             str = "TCH/H + ACCHs, Subchannel";
1614             subchannel = ((oct8 & 0x08)>>3);
1615         }
1616         else if ((oct8 & 0xe0) == 0x20)
1617         {
1618             str = "SDCCH/4 + SACCH/C4 or CBCH (SDCCH/4), Subchannel";
1619             subchannel = ((oct8 & 0x18)>>3);
1620         }
1621         else if ((oct8 & 0xc0) == 0x40)
1622         {
1623             str = "SDCCH/8 + SACCH/C8 or CBCH (SDCCH/8), Subchannel";
1624             subchannel = ((oct8 & 0x38)>>3);
1625         } else {
1626             str = "Unknown channel information";
1627             subchannel = oct8;
1628         }
1629
1630         other_decode_bitfield_value(a_bigbuf, oct8, 0xf8, 8);
1631         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s %d",a_bigbuf,str,subchannel);
1632     }
1633
1634     other_decode_bitfield_value(a_bigbuf, oct8, 0x07, 8);
1635     proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Timeslot: %d",a_bigbuf,(oct8 & 0x07));
1636
1637     curr_offset +=1;
1638
1639     /* Octet 3 */
1640     oct8 = tvb_get_guint8(tvb, curr_offset);
1641     other_decode_bitfield_value(a_bigbuf, oct8, 0xe0, 8);
1642     proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Training Sequence: %d",a_bigbuf,((oct8 & 0xe0)>>5));
1643
1644
1645     if ((oct8 & 0x10) == 0x10)
1646     {
1647         /* Hopping sequence */
1648         maio = ((oct8 & 0x0f)<<2) | ((tvb_get_guint8(tvb,curr_offset+1) & 0xc0) >> 6);
1649         hsn = (tvb_get_guint8(tvb,curr_offset+1) & 0x3f);
1650         str = "Yes";
1651
1652         other_decode_bitfield_value(a_bigbuf, oct8, 0x10, 8);
1653         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Hopping channel: %s",a_bigbuf,str);
1654         proto_tree_add_text(subtree,tvb, curr_offset, 2,"Hopping channel: MAIO %d",maio);
1655         proto_tree_add_text(subtree,tvb, curr_offset, 2,"Hopping channel: HSN %d",hsn);
1656     }
1657     else
1658     {
1659         /* single ARFCN */
1660         arfcn = ((oct8 & 0x03) << 8) | tvb_get_guint8(tvb,curr_offset+1);
1661         str = "No";
1662
1663         other_decode_bitfield_value(a_bigbuf, oct8, 0x10, 8);
1664         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Hopping channel: %s",a_bigbuf,str);
1665         other_decode_bitfield_value(a_bigbuf, oct8, 0x0c, 8);
1666         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Spare",a_bigbuf);
1667         proto_tree_add_text(subtree,tvb, curr_offset, 2,"Single channel : ARFCN %d",arfcn);
1668     }
1669
1670     curr_offset = curr_offset + 2;
1671
1672     return(curr_offset - offset);
1673 }
1674 /*
1675  * [3] 10.5.2.5a Channel Description 2
1676  */
1677 static guint16
1678 de_rr_ch_dsc2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
1679 {
1680     guint32     curr_offset;
1681     guint8      oct8,subchannel;
1682     guint16 arfcn, hsn, maio;
1683     proto_tree  *subtree;
1684     proto_item  *item;
1685     const gchar *str;
1686
1687     curr_offset = offset;
1688
1689     item = proto_tree_add_text(tree,tvb, curr_offset, 3, "%s", gsm_rr_elem_strings[DE_RR_CH_DSC2].strptr);
1690
1691     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_CH_DSC2]);
1692
1693     /* Octet 2 */
1694     oct8 = tvb_get_guint8(tvb, curr_offset);
1695
1696     if ((oct8 & 0xf8) == 0x0)
1697     {
1698         str = "TCH/F + FACCH/F and SACCH/M";
1699         other_decode_bitfield_value(a_bigbuf, oct8, 0xf8, 8);
1700         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s",a_bigbuf,str);
1701     }
1702     else if ((oct8 & 0xf8) == 0x08)
1703     {
1704         str = "TCH/F + FACCH/F and SACCH/F";
1705         other_decode_bitfield_value(a_bigbuf, oct8, 0xf8, 8);
1706         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s",a_bigbuf,str);
1707     }
1708     else if ((oct8 & 0xf8) == 0xf0)
1709     {
1710         str = "TCH/F + FACCH/F and SACCH/M + bi- and unidirectional channels";
1711         other_decode_bitfield_value(a_bigbuf, oct8, 0xf8, 8);
1712         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s",a_bigbuf,str);
1713     }
1714     else
1715     {
1716         if ((oct8 & 0xf0) == 0x10)
1717         {
1718             str = "TCH/H + ACCHs, Subchannel";
1719             subchannel = ((oct8 & 0x08)>>3);
1720         }
1721         else if ((oct8 & 0xe0) == 0x20)
1722         {
1723             str = "SDCCH/4 + SACCH/C4 or CBCH (SDCCH/4), Subchannel";
1724             subchannel = ((oct8 & 0x18)>>3);
1725         }
1726         else if ((oct8 & 0xc0) == 0x40)
1727         {
1728             str = "SDCCH/8 + SACCH/C8 or CBCH (SDCCH/8), Subchannel";
1729             subchannel = ((oct8 % 0x38)>>3);
1730         }
1731         else if ((oct8 & 0xc0) == 0x80)
1732         {
1733             str = "TCH/F + FACCH/F and SACCH/M + bidirectional channels at timeslot";
1734             subchannel = ((oct8 % 0x38)>>3);
1735         }
1736         else if ((oct8 & 0xe0) == 0xc0)
1737         {
1738             str = "TCH/F + FACCH/F and SACCH/M + unidirectional channels at timeslot";
1739             subchannel = ((oct8 % 0x38)>>3);
1740         } else {
1741             str = "Unknown channel information";
1742             subchannel = oct8;
1743         }
1744         other_decode_bitfield_value(a_bigbuf, oct8, 0xf8, 8);
1745         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s %d",a_bigbuf,str,subchannel);
1746     }
1747
1748     other_decode_bitfield_value(a_bigbuf, oct8, 0x07, 8);
1749     proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Timeslot: %d",a_bigbuf,(oct8 & 0x07));
1750
1751     curr_offset +=1;
1752
1753     /* Octet 3 */
1754     oct8 = tvb_get_guint8(tvb, curr_offset);
1755     other_decode_bitfield_value(a_bigbuf, oct8, 0xe0, 8);
1756     proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Training Sequence: %d",a_bigbuf,((oct8 & 0xe0)>>5));
1757
1758     if ((oct8 & 0x10) == 0x10)
1759     {
1760         /* Hopping sequence */
1761         maio = ((oct8 & 0x0f)<<2) | ((tvb_get_guint8(tvb,curr_offset+1) & 0xc0) >> 6);
1762         hsn = (tvb_get_guint8(tvb,curr_offset+1) & 0x3f);
1763         str = "Yes";
1764
1765         other_decode_bitfield_value(a_bigbuf, oct8, 0x10, 8);
1766         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Hopping channel: %s",a_bigbuf,str);
1767         proto_tree_add_text(subtree,tvb, curr_offset, 2,"Hopping channel: MAIO %d",maio);
1768         proto_tree_add_text(subtree,tvb, curr_offset, 2,"Hopping channel: HSN %d",hsn);
1769     }
1770     else
1771     {
1772         /* single ARFCN */
1773         arfcn = ((oct8 & 0x03) << 8) | tvb_get_guint8(tvb,curr_offset+1);
1774         str = "No";
1775
1776         other_decode_bitfield_value(a_bigbuf, oct8, 0x10, 8);
1777         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Hopping channel: %s",a_bigbuf,str);
1778         other_decode_bitfield_value(a_bigbuf, oct8, 0x0c, 8);
1779         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Spare",a_bigbuf);
1780         proto_tree_add_text(subtree,tvb, curr_offset, 2,"Single channel : ARFCN %d",arfcn);
1781     }
1782
1783     curr_offset = curr_offset + 2;
1784
1785     return(curr_offset - offset);
1786 }
1787
1788 /*
1789  * [3] 10.5.2.5c Channel Description 3
1790  */
1791 static guint16
1792 de_rr_ch_dsc3(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
1793 {
1794     guint32     curr_offset;
1795     guint8      oct8;
1796     guint16 arfcn, hsn, maio;
1797     proto_tree  *subtree;
1798     proto_item  *item;
1799     const gchar *str;
1800
1801     curr_offset = offset;
1802
1803     item = proto_tree_add_text(tree,tvb, curr_offset, 3, "%s", gsm_rr_elem_strings[DE_RR_CH_DSC3].strptr);
1804
1805     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_CH_DSC3]);
1806
1807     /* Octet 2 */
1808     oct8 = tvb_get_guint8(tvb, curr_offset);
1809     other_decode_bitfield_value(a_bigbuf, oct8, 0xe0, 8);
1810     proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Training Sequence: %d",a_bigbuf,((oct8 & 0xe0)>>5));
1811
1812     if ((oct8 & 0x10) == 0x10)
1813     {
1814         /* Hopping sequence */
1815         maio = ((oct8 & 0x0f)<<2) | ((tvb_get_guint8(tvb,curr_offset+1) & 0xc0) >> 6);
1816         hsn = (tvb_get_guint8(tvb,curr_offset+1) & 0x3f);
1817         str = "Yes";
1818
1819         other_decode_bitfield_value(a_bigbuf, oct8, 0x10, 8);
1820         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Hopping channel: %s",a_bigbuf,str);
1821         proto_tree_add_text(subtree,tvb, curr_offset, 2,"Hopping channel: MAIO %d",maio);
1822         proto_tree_add_text(subtree,tvb, curr_offset, 2,"Hopping channel: HSN %d",hsn);
1823     }
1824     else
1825     {
1826         /* single ARFCN */
1827         arfcn = ((oct8 & 0x03) << 8) | tvb_get_guint8(tvb,curr_offset+1);
1828         str = "No";
1829
1830         other_decode_bitfield_value(a_bigbuf, oct8, 0x10, 8);
1831         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Hopping channel: %s",a_bigbuf,str);
1832         other_decode_bitfield_value(a_bigbuf, oct8, 0x0c, 8);
1833         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Spare",a_bigbuf);
1834         proto_tree_add_text(subtree,tvb, curr_offset, 2,"Single channel : ARFCN %d",arfcn);
1835     }
1836
1837     curr_offset = curr_offset + 2;
1838
1839     return(curr_offset - offset);
1840 }
1841
1842 /*
1843  * [3] 10.5.2.6 Channel Mode
1844  */
1845 /* Channel Mode  */
1846 static const value_string gsm_a_rr_channel_mode_vals[] = {
1847     { 0x00, "signalling only"},
1848     { 0x01, "speech full rate or half rate version 1(GSM FR or GSM HR)"},
1849     { 0x21, "speech full rate or half rate version 2(GSM EFR)"},
1850     { 0x41, "speech full rate or half rate version 3(FR AMR or HR AMR)"},
1851     { 0x81, "speech full rate or half rate version 4(OFR AMR-WB or OHR AMR-WB)"},
1852     { 0x82, "speech full rate or half rate version 5(FR AMR-WB )"},
1853     { 0x83, "speech full rate or half rate version 6(OHR AMR )"},
1854     { 0x61, "data, 43.5 kbit/s (downlink)+14.5 kbps (uplink)"},
1855     { 0x62, "data, 29.0 kbit/s (downlink)+14.5 kbps (uplink)"},
1856     { 0x64, "data, 43.5 kbit/s (downlink)+29.0 kbps (uplink)"},
1857     { 0x67, "data, 14.5 kbit/s (downlink)+43.5 kbps (uplink)"},
1858     { 0x65, "data, 14.5 kbit/s (downlink)+29.0 kbps (uplink)"},
1859     { 0x66, "data, 29.0 kbit/s (downlink)+43.5 kbps (uplink)"},
1860     { 0x27, "data, 43.5 kbit/s radio interface rate"},
1861     { 0x63, "data, 32.0 kbit/s radio interface rate"},
1862     { 0x43, "data, 29.0 kbit/s radio interface rate"},
1863     { 0x0f, "data, 14.5 kbit/s radio interface rate"},
1864     { 0x03, "data, 12.0 kbit/s radio interface rate"},
1865     { 0x0b, "data, 6.0 kbit/s radio interface rate"},
1866     { 0x13, "data, 3.6 kbit/s radio interface rate"},
1867     {    0, NULL }
1868 };
1869
1870 guint16
1871 de_rr_ch_mode(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
1872 {
1873     guint32     curr_offset;
1874
1875     curr_offset = offset;
1876
1877     proto_tree_add_item(tree, hf_gsm_a_rr_channel_mode, tvb, curr_offset, 1, FALSE);
1878
1879     curr_offset = curr_offset + 1;
1880
1881     return(curr_offset - offset);
1882 }
1883 /*
1884  * [3] 10.5.2.7 Channel Mode 2
1885  */
1886
1887 static const value_string gsm_a_rr_channel_mode2_vals[] = {
1888     { 0x00, "signalling only"},
1889     { 0x05, "speech half rate version 1(GSM HR)"},
1890     { 0x25, "speech half rate version 2(GSM EFR)"},
1891     { 0x45, "speech half rate version 3(HR AMR)"},
1892     { 0x85, "speech half rate version 4(OHR AMR-WB)"},
1893     { 0x06, "speech half rate version 6(OHR AMR )"},
1894     { 0x0f, "data, 6.0 kbit/s radio interface rate"},
1895     { 0x17, "data, 3.6 kbit/s radio interface rate"},
1896     {    0, NULL }
1897 };
1898
1899 static guint16
1900 de_rr_ch_mode2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
1901 {
1902     guint32     curr_offset;
1903
1904     curr_offset = offset;
1905
1906     proto_tree_add_item(tree, hf_gsm_a_rr_channel_mode2, tvb, curr_offset, 1, FALSE);
1907
1908     curr_offset = curr_offset + 1;
1909
1910     return(curr_offset - offset);
1911 }
1912 /*
1913  * [3] 10.5.2.7a UTRAN Classmark information element
1914  */
1915 static guint16
1916 de_rr_utran_cm(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
1917 {
1918     guint32 curr_offset;
1919     tvbuff_t *rrc_irat_ho_info_tvb;
1920
1921     curr_offset = offset;
1922     if (len)
1923     {
1924         rrc_irat_ho_info_tvb = tvb_new_subset(tvb, curr_offset, len, len);
1925         if (rrc_irat_ho_info_handle && gsm_a_dtap_pinfo)
1926                         /* gsm_a_dtap_pinfo MUST be set by any dissector calling de_rr_utran_cm */
1927             call_dissector(rrc_irat_ho_info_handle, rrc_irat_ho_info_tvb, gsm_a_dtap_pinfo, tree);
1928     }
1929
1930     curr_offset += len;
1931     return(curr_offset - offset);
1932 }
1933
1934 /*
1935  * [3] 10.5.2.7b (void)
1936  */
1937
1938 /*
1939  * [3] 10.5.2.7c Classmark Enquiry Mask
1940  * Bit 8:
1941  * 0    CLASSMARK CHANGE message is requested
1942  * 1    CLASSMARK CHANGE message is not requested
1943  * Bits 7-5 . 5
1944  * 000  UTRAN CLASSMARK CHANGE message including status on predefined configurations (i.e. Sequence Description) is requested
1945  * 111  UTRAN CLASSMARK CHANGE message including status on predefined configurations (i.e. Sequence Description) is not requested.
1946  * All other values shall not be sent. If received, they shall be interpreted as '000'.
1947  * Bit 4:
1948  * 0    CDMA2000 CLASSMARK CHANGE message requested
1949  * 1    CDMA2000 CLASSMARK CHANGE message not requested.
1950  * Bit 3:
1951  * 0    GERAN IU MODE CLASSMARK CHANGE message requested
1952  * 1    GERAN IU MODE CLASSMARK CHANGE message not requested.
1953  * Bits 2 - 1: spare(0).
1954  */
1955 static const true_false_string gsm_a_msg_req_value  = {
1956     "message is not requested",
1957     "message is requested"
1958 };
1959
1960 static const value_string gsm_a_rr_utran_cm_cng_msg_req_vals[] = {
1961     { 0x0, "message including status on predefined configurations (i.e. Sequence Description) is requested"},
1962     { 0x1, "message including status on predefined configurations (i.e. Sequence Description) is requested"},
1963     { 0x2, "message including status on predefined configurations (i.e. Sequence Description) is requested"},
1964     { 0x3, "message including status on predefined configurations (i.e. Sequence Description) is requested"},
1965     { 0x4, "message including status on predefined configurations (i.e. Sequence Description) is requested"},
1966     { 0x5, "message including status on predefined configurations (i.e. Sequence Description) is requested"},
1967     { 0x6, "message including status on predefined configurations (i.e. Sequence Description) is requested"},
1968     { 0x7, "message including status on predefined configurations (i.e. Sequence Description) is not requested."},
1969     {   0, NULL }
1970 };
1971 guint16
1972 de_rr_cm_enq_mask(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
1973 {
1974     guint32     curr_offset;
1975
1976     curr_offset = offset;
1977
1978     proto_tree_add_item(tree, hf_gsm_a_rr_cm_cng_msg_req, tvb, curr_offset, 1, FALSE);
1979     proto_tree_add_item(tree, hf_gsm_a_rr_utran_cm_cng_msg_req, tvb, curr_offset, 1, FALSE);
1980     proto_tree_add_item(tree, hf_gsm_a_rr_cdma200_cm_cng_msg_req, tvb, curr_offset, 1, FALSE);
1981     proto_tree_add_item(tree, hf_gsm_a_rr_geran_iu_cm_cng_msg_req, tvb, curr_offset, 1, FALSE);
1982
1983     curr_offset = curr_offset + 1;
1984
1985     return(curr_offset - offset);
1986 }
1987 /*
1988  * [3] 10.5.2.8 Channel Needed
1989  */
1990 static const value_string gsm_a_rr_channel_needed_vals[] = {
1991     { 0x00, "Any channel"},
1992     { 0x01, "SDCCH"},
1993     { 0x02, "TCH/F (Full rate)"},
1994     { 0x03, "TCH/H or TCH/F (Dual rate)"},
1995     {    0, NULL }
1996 };
1997 guint16
1998 de_rr_chnl_needed(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
1999 {
2000     proto_tree  *subtree;
2001     proto_item  *item;
2002     guint32     curr_offset;
2003     gint bit_offset;
2004
2005     curr_offset = offset;
2006     if (UPPER_NIBBLE==len)
2007         bit_offset = 4;
2008     else
2009         bit_offset = 0;
2010
2011     item = proto_tree_add_text(tree, tvb, curr_offset, 3, "%s",
2012                                gsm_rr_elem_strings[DE_RR_CHNL_NEEDED].strptr);
2013
2014     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_CHNL_NEEDED]);
2015
2016     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_chnl_needed_ch1, tvb, (curr_offset<<3)+bit_offset+2, 2, FALSE);
2017     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_chnl_needed_ch2, tvb, (curr_offset<<3)+bit_offset, 2, FALSE);
2018
2019     curr_offset = curr_offset + 1;
2020
2021     return(curr_offset - offset);
2022 }
2023 /*
2024  * [3] 10.5.2.8a Channel Request Description
2025  * [3] 10.5.2.8b Channel Request Description 2
2026  */
2027 /*
2028  * [3] 10.5.2.9 Cipher Mode Setting
2029  */
2030 /* SC (octet 1) */
2031 static const value_string gsm_a_rr_sc_vals[] = {
2032     { 0, "No ciphering"},
2033     { 1, "Start ciphering"},
2034     { 0, NULL }
2035 };
2036 /* algorithm identifier
2037  * If SC=1 then:
2038  * bits
2039  * 4 3 2
2040  */
2041 guint16
2042 de_rr_cip_mode_set(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2043 {
2044     guint32     curr_offset;
2045     gint bit_offset;
2046     guint64 value;
2047
2048     curr_offset = offset;
2049
2050     /* Cipher Mode Setting
2051      * Note: The coding of fields SC and algorithm identifier is defined in [44.018]
2052      * as part of the Cipher Mode Setting IE.
2053      */
2054     if (UPPER_NIBBLE==len)
2055         bit_offset = 4;
2056     else
2057         bit_offset = 0;
2058
2059     proto_tree_add_bits_ret_val(tree, hf_gsm_a_rr_sc, tvb, (curr_offset<<3)+bit_offset+3, 1, &value, FALSE);
2060     if (value == 1){ /* Start ciphering */
2061         /* algorithm identifier */
2062         proto_tree_add_bits_item(tree, hf_gsm_a_algorithm_id, tvb, (curr_offset<<3)+bit_offset, 3, FALSE);
2063     }
2064     curr_offset = curr_offset + 1;
2065
2066     return(curr_offset - offset);
2067 }
2068 /*
2069  * [3] 10.5.2.10 Cipher Response
2070  */
2071 /* CR (octet 1) */
2072 static const value_string gsm_a_rr_cr_vals[] = {
2073     { 0, "IMEISV shall not be included"},
2074     { 1, "IMEISV shall be included"},
2075     { 0, NULL }
2076 };
2077
2078 static guint16
2079 de_rr_cip_mode_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2080 {
2081     guint32     curr_offset;
2082     gint bit_offset;
2083
2084     curr_offset = offset;
2085     if (UPPER_NIBBLE==len)
2086         bit_offset = 4;
2087     else
2088         bit_offset = 0;
2089
2090     /* Cipher Mode Response
2091      * Note: The coding of field CR is defined in [44.018]
2092      * as part of the Cipher Mode Response IE.
2093      */
2094     proto_tree_add_bits_item(tree, hf_gsm_a_rr_cr, tvb, (curr_offset<<3)+bit_offset+3, 1, FALSE);
2095     curr_offset = curr_offset + 1;
2096
2097     return(curr_offset - offset);
2098 }
2099 /* [3] 10.5.2.11 Control Channel Description */
2100
2101 static const value_string gsm_a_rr_mscr_vals[] = {
2102     { 0, "MSC is Release '98 or older"},
2103     { 1, "MSC is Release '99 onwards"},
2104     { 0, NULL }
2105 };
2106
2107 static const value_string gsm_a_rr_att_vals[] = {
2108     { 0, "MSs in the cell are not allowed to apply IMSI attach and detach procedure"},
2109     { 1, "MSs in the cell shall apply IMSI attach and detach procedure"},
2110     { 0, NULL }
2111 };
2112
2113 static const value_string gsm_a_rr_ccch_conf_vals[] = {
2114     { 0, "1 basic physical channel used for CCCH, not combined with SDCCHs"},
2115     { 1, "1 basic physical channel used for CCCH, combined with SDCCHs"},
2116     { 2, "2 basic physical channels used for CCCH, not combined with SDCCHs"},
2117     { 3, "Reserved"},
2118     { 4, "3 basic physical channels used for CCCH, not combined with SDCCHs"},
2119     { 5, "Reserved"},
2120     { 6, "4 basic physical channels used for CCCH, not combined with SDCCHs"},
2121     { 7, "Reserved"},
2122     { 0, NULL }
2123 };
2124
2125 static const value_string gsm_a_rr_cbq3_vals[] = {
2126     { 0, "Iu mode not supported"},
2127     { 1, "Iu mode capable MSs barred"},
2128     { 2, "Iu mode supported, cell not barred"},
2129     { 3, "Iu mode supported, cell not barred"},
2130     { 0, NULL }
2131 };
2132
2133 static guint16
2134 de_rr_ctrl_ch_desc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2135 {
2136     proto_tree  *subtree;
2137     proto_item  *item;
2138     guint8      oct;
2139     guint32     curr_offset;
2140
2141     curr_offset = offset;
2142
2143     item = proto_tree_add_text(tree, tvb, curr_offset, 3, "%s",
2144                                gsm_rr_elem_strings[DE_RR_CTRL_CH_DESC].strptr);
2145
2146     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_CTRL_CH_DESC]);
2147
2148     proto_tree_add_item(subtree, hf_gsm_a_rr_mscr, tvb, curr_offset, 1, FALSE);
2149     proto_tree_add_item(subtree, hf_gsm_a_rr_att, tvb, curr_offset, 1, FALSE);
2150     proto_tree_add_item(subtree, hf_gsm_a_rr_bs_ag_blks_res, tvb, curr_offset, 1, FALSE);
2151     proto_tree_add_item(subtree, hf_gsm_a_rr_ccch_conf, tvb, curr_offset, 1, FALSE);
2152
2153     curr_offset = curr_offset + 1;
2154     oct = tvb_get_guint8(tvb, curr_offset);
2155
2156     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_cbq3, tvb, (curr_offset<<3)+1, 2, FALSE);
2157     proto_tree_add_uint(subtree, hf_gsm_a_rr_bs_pa_mfrms, tvb, curr_offset, 1, (oct&0x07)+2);
2158
2159     curr_offset = curr_offset + 1;
2160
2161     proto_tree_add_item(subtree, hf_gsm_a_rr_t3212, tvb, curr_offset, 1, FALSE);
2162
2163     curr_offset = curr_offset + 1;
2164
2165     return(curr_offset - offset);
2166 }
2167
2168 /* [3] 10.5.2.11a DTM Information Details
2169  */
2170 /*
2171  * [3]  10.5.2.11b      Dynamic ARFCN Mapping
2172  */
2173 static const value_string gsm_a_rr_gsm_band_vals[] = {
2174     {  0, "GSM 750"},
2175     {  1, "DCS 1800"},
2176     {  2, "PCS 1900"},
2177     {  3, "GSM T 380"},
2178     {  4, "GSM T 410"},
2179     {  5, "GSM T 900"},
2180     {  6, "GSM 710"},
2181     {  7, "GSM T 810"},
2182     {  8, "Reserved"},
2183     {  9, "Reserved"},
2184     { 10, "Reserved"},
2185     { 11, "Reserved"},
2186     { 12, "Reserved"},
2187     { 13, "Reserved"},
2188     { 14, "Reserved"},
2189     { 15, "Reserved"},
2190     {  0, NULL }
2191 };
2192
2193
2194 static guint16
2195 de_rr_dyn_arfcn_map(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2196 {
2197     guint32     curr_offset;
2198     gint bit_offset;
2199     guint64 length;
2200     guint value;
2201
2202     curr_offset = offset;
2203     bit_offset = curr_offset << 3;
2204
2205     proto_tree_add_bits_ret_val(tree, hf_gsm_a_rr_dyn_arfcn_length, tvb, bit_offset, 8, &length, FALSE);
2206     value = tvb_get_bits8(tvb,bit_offset,1);
2207     bit_offset += 1;
2208     while (value && length)
2209     {
2210         proto_tree_add_bits_item(tree, hf_gsm_a_rr_gsm_band, tvb, bit_offset, 4, FALSE);
2211         bit_offset += 4;
2212         proto_tree_add_bits_item(tree, hf_gsm_a_rr_arfcn_first, tvb, bit_offset, 10, FALSE);
2213         bit_offset += 10;
2214         proto_tree_add_bits_item(tree, hf_gsm_a_rr_band_offset, tvb, bit_offset, 10, FALSE);
2215         bit_offset += 10;
2216         proto_tree_add_bits_item(tree, hf_gsm_a_rr_arfcn_range, tvb, bit_offset, 7, FALSE);
2217         bit_offset += 7;
2218         value = tvb_get_bits8(tvb,bit_offset,1);
2219         bit_offset += 1;
2220         length -= 4;
2221     }
2222
2223     curr_offset = curr_offset + len;
2224
2225     return(curr_offset - offset);
2226 }
2227 /*
2228  * [3] 10.5.2.12 Frequency Channel Sequence
2229  */
2230 static guint16
2231 de_rr_freq_ch_seq(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2232 {
2233     guint32     curr_offset;
2234     gint bit_offset, i;
2235
2236     curr_offset = offset;
2237
2238     proto_tree_add_item(tree, hf_gsm_a_rr_lowest_arfcn, tvb, curr_offset, 1, FALSE);
2239     curr_offset += 1;
2240     bit_offset = curr_offset << 3;
2241     for (i=0; i<16; i++)
2242     {
2243         proto_tree_add_bits_item(tree, hf_gsm_a_rr_inc_skip_arfcn, tvb, bit_offset, 4, FALSE);
2244         bit_offset += 4;
2245     }
2246
2247     curr_offset = curr_offset + 8;
2248
2249     return(curr_offset - offset);
2250 }
2251
2252 /*
2253  * [3] 10.5.2.13 Frequency List
2254  */
2255 /*
2256  * [3] 10.5.2.13 Frequency List
2257  *
2258  * Bit Bit Bit Bit Bit format notation
2259  * 8 7  4 3 2
2260  * 0 0  X X X bit map 0
2261  * 1 0  0 X X 1024 range
2262  * 1 0  1 0 0 512 range
2263  * 1 0  1 0 1 256 range
2264  * 1 0  1 1 0 128 range
2265  * 1 0  1 1 1 variable bit map
2266  */
2267 /* The mask 0xce (1100 1110) will produce the result 0110 0111*/
2268 static const value_string gsm_a_rr_freq_list_format_id_vals[] = {
2269     { 0x00, "bit map 0"},
2270     { 0x02, "bit map 0"},
2271     { 0x04, "bit map 0"},
2272     { 0x06, "bit map 0"},
2273     { 0x08, "bit map 0"},
2274     { 0x0a, "bit map 0"},
2275     { 0x0c, "bit map 0"},
2276     { 0x0e, "bit map 0"},
2277     { 0x40, "1024 range"},
2278     { 0x41, "1024 range"},
2279     { 0x42, "1024 range"},
2280     { 0x43, "1024 range"},
2281     { 0x44, "512 range"},
2282     { 0x45, "256 range"},
2283     { 0x46, "128 range"},
2284     { 0x47, "variable bit map"},
2285     { 0x00, NULL }
2286 };
2287
2288 static guint16
2289 de_rr_freq_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2290 {
2291     return dissect_arfcn_list(tvb, tree, offset, len, add_string, string_len);
2292 }
2293 /*
2294  * [3] 10.5.2.14 Frequency Short List
2295  *
2296  *The Frequency Short List information element is a type 3 information element of 10 octet length.
2297  *
2298  * This element is encoded exactly as the Frequency List information element,
2299  * except that it has a fixed length instead of a variable length and does
2300  * not contain a length indicator and that it shall not be encoded in bitmap 0 format.
2301  */
2302
2303  static guint16
2304 de_rr_freq_short_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2305  {
2306      return dissect_arfcn_list(tvb, tree, offset, 9, add_string, string_len);
2307  }
2308
2309 /*
2310  * [3] 10.5.2.14a Frequency Short List 2
2311  *
2312  * The Frequency Short List information element is a type 3 information element of 8 octet length.
2313  *
2314  * This element is encoded exactly as the Frequency List information element,
2315  * except that it has a fixed length instead of a variable length and does
2316  * not contain a length indicator and that it shall not be encoded in bitmap 0 format.
2317  */
2318 static guint16
2319 de_rr_freq_short_list2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2320 {
2321     return dissect_arfcn_list(tvb, tree, offset, 8, add_string, string_len);
2322 }
2323 /*
2324  * [3] 10.5.2.14b Group Channel Description
2325  */
2326
2327 /*
2328  * [3] 10.5.2.14c GPRS Resumption
2329  */
2330 static const true_false_string gsm_a_rr_gprs_resumption_ack_value  = {
2331     "Resumption of GPRS services successfully acknowledged",
2332     "Resumption of GPRS services not successfully acknowledged"
2333 };
2334
2335 static guint16
2336 de_rr_gprs_resumption(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2337 {
2338     guint32 curr_offset;
2339
2340     curr_offset = offset;
2341
2342     proto_tree_add_item(tree, hf_gsm_a_rr_gprs_resumption_ack, tvb, curr_offset, 1, FALSE);
2343     curr_offset += 1;
2344
2345     return (curr_offset - offset);
2346 }
2347
2348 /*
2349  * [3] 10.5.2.14d GPRS broadcast information
2350  */
2351
2352 static gint
2353 de_rr_rest_oct_gprs_cell_options(tvbuff_t *tvb, proto_tree *tree, gint bit_offset)
2354 {
2355     proto_tree *subtree, *subtree2;
2356     proto_item *item, *item2;
2357     gint curr_bit_offset, curr_bit_offset_sav;
2358     guint8 value;
2359
2360     curr_bit_offset = bit_offset;
2361
2362     item = proto_tree_add_text(tree, tvb, curr_bit_offset>>3, -1, "%s", gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_GPRS_CELL_OPTIONS].strptr);
2363     subtree = proto_item_add_subtree(item, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_GPRS_CELL_OPTIONS]);
2364     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_nmo, tvb, curr_bit_offset, 2, FALSE);
2365     curr_bit_offset += 2;
2366     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_t3168, tvb, curr_bit_offset, 3, FALSE);
2367     curr_bit_offset += 3;
2368     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_t3192, tvb, curr_bit_offset, 3, FALSE);
2369     curr_bit_offset += 3;
2370     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_drx_timer_max, tvb, curr_bit_offset, 3, FALSE);
2371     curr_bit_offset += 3;
2372     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_access_burst_type, tvb, curr_bit_offset, 1, FALSE);
2373     curr_bit_offset += 1;
2374     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_control_ack_type, tvb, curr_bit_offset, 1, FALSE);
2375     curr_bit_offset += 1;
2376     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_bs_cv_max, tvb, curr_bit_offset, 4, FALSE);
2377     curr_bit_offset += 4;
2378     if (tvb_get_bits8(tvb,curr_bit_offset,1))
2379     {
2380         curr_bit_offset += 1;
2381         proto_tree_add_bits_item(subtree, hf_gsm_a_rr_pan_dec, tvb, curr_bit_offset, 3, FALSE);
2382         curr_bit_offset += 3;
2383         proto_tree_add_bits_item(subtree, hf_gsm_a_rr_pan_inc, tvb, curr_bit_offset, 3, FALSE);
2384         curr_bit_offset += 3;
2385         proto_tree_add_bits_item(subtree, hf_gsm_a_rr_pan_max, tvb, curr_bit_offset, 3, FALSE);
2386         curr_bit_offset += 3;
2387     }
2388     else
2389         curr_bit_offset += 1;
2390     if (tvb_get_bits8(tvb,curr_bit_offset,1))
2391     { /* Optional extension information */
2392         curr_bit_offset += 1;
2393         curr_bit_offset_sav = curr_bit_offset;
2394         item2 = proto_tree_add_text(subtree, tvb, curr_bit_offset>>3, -1, "%s",
2395                                     gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_GPRS_CELL_OPTIONS_EXT_INFO].strptr);
2396         subtree2 = proto_item_add_subtree(item2, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_GPRS_CELL_OPTIONS_EXT_INFO]);
2397         value = tvb_get_bits8(tvb,curr_bit_offset,6);
2398         proto_tree_add_text(subtree2,tvb, curr_bit_offset>>3, 1, "Extension Length: %d", value);
2399         curr_bit_offset += 6;
2400         value += 1;
2401         proto_item_set_len(item2,((curr_bit_offset+value-curr_bit_offset_sav)>>3)+1);
2402         if (tvb_get_bits8(tvb,curr_bit_offset,1))
2403         {
2404             curr_bit_offset += 1;
2405             proto_tree_add_bits_item(subtree2, hf_gsm_a_rr_egprs_packet_channel_request, tvb, curr_bit_offset, 1, FALSE);
2406             curr_bit_offset += 1;
2407             proto_tree_add_bits_item(subtree2, hf_gsm_a_rr_bep_period, tvb, curr_bit_offset, 4, FALSE);
2408             curr_bit_offset += 4;
2409             value -= 5;
2410         }
2411         else
2412             curr_bit_offset += 1;
2413         value -= 1;
2414         proto_tree_add_bits_item(subtree2, hf_gsm_a_rr_pfc_feature_mode, tvb, curr_bit_offset, 1, FALSE);
2415         curr_bit_offset += 1;
2416         proto_tree_add_bits_item(subtree2, hf_gsm_a_rr_dtm_support, tvb, curr_bit_offset, 1, FALSE);
2417         curr_bit_offset += 1;
2418         proto_tree_add_bits_item(subtree2, hf_gsm_a_rr_bss_paging_coordination, tvb, curr_bit_offset, 1, FALSE);
2419         curr_bit_offset += 1;
2420         value -= 3;
2421         if (value > 0)
2422         { /* Rel 4 extension */
2423             proto_tree_add_bits_item(subtree2, hf_gsm_a_rr_ccn_active, tvb, curr_bit_offset, 1, FALSE);
2424             curr_bit_offset += 1;
2425             proto_tree_add_bits_item(subtree2, hf_gsm_a_rr_nw_ext_utbf, tvb, curr_bit_offset, 1, FALSE);
2426             curr_bit_offset += 1;
2427             value -= 2;
2428             if (value > 0)
2429             { /* Rel 6 extension */
2430                 proto_tree_add_bits_item(subtree2, hf_gsm_a_rr_multiple_tbf_capability, tvb, curr_bit_offset, 1, FALSE);
2431                 curr_bit_offset += 1;
2432                 proto_tree_add_bits_item(subtree2, hf_gsm_a_rr_ext_utbf_no_data, tvb, curr_bit_offset, 1, FALSE);
2433                 curr_bit_offset += 1;
2434                 proto_tree_add_bits_item(subtree2, hf_gsm_a_rr_dtm_enhancements_capability, tvb, curr_bit_offset, 1, FALSE);
2435                 curr_bit_offset += 1;
2436                 value -= 3;
2437                 if (tvb_get_bits8(tvb,curr_bit_offset,1))
2438                 {
2439                     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_dedicated_mode_mbms_notification_support, tvb, bit_offset, 1, FALSE);
2440                     bit_offset += 1;
2441                     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_mnci_support, tvb, bit_offset, 1, FALSE);
2442                     bit_offset += 1;
2443                     value -= 2;
2444                 }
2445                 else
2446                     bit_offset += 1;
2447                 value -= 1;
2448                 if (value > 0)
2449                 { /* Rel 7 extension */
2450                     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_reduced_latency_access, tvb, bit_offset, 1, FALSE);
2451                     bit_offset += 1;
2452                     value -= 1;
2453                 }
2454             }
2455         }
2456         curr_bit_offset += value;
2457     }
2458     else
2459         curr_bit_offset += 1;
2460     proto_item_set_len(item,((curr_bit_offset-bit_offset)>>3)+1);
2461
2462     return (curr_bit_offset - bit_offset);
2463 }
2464
2465 static gint
2466 de_rr_rest_oct_gprs_power_control_parameters(tvbuff_t *tvb, proto_tree *tree, gint bit_offset)
2467 {
2468     proto_tree *subtree;
2469     proto_item *item;
2470     gint curr_bit_offset;
2471
2472     curr_bit_offset = bit_offset;
2473
2474     item = proto_tree_add_text(tree, tvb, curr_bit_offset>>3, -1, "%s", gsm_rr_rest_octets_elem_strings[DE_RR_REST_OCTETS_GPRS_POWER_CONTROL_PARAMS].strptr);
2475     subtree = proto_item_add_subtree(item, ett_gsm_rr_rest_octets_elem[DE_RR_REST_OCTETS_GPRS_POWER_CONTROL_PARAMS]);
2476     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_alpha, tvb, curr_bit_offset, 4, FALSE);
2477     curr_bit_offset += 4;
2478     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_t_avg_w, tvb, curr_bit_offset, 5, FALSE);
2479     curr_bit_offset += 5;
2480     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_t_avg_t, tvb, curr_bit_offset, 5, FALSE);
2481     curr_bit_offset += 5;
2482     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_pc_meas_chan, tvb, curr_bit_offset, 1, FALSE);
2483     curr_bit_offset += 1;
2484     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_n_avg_i, tvb, curr_bit_offset, 4, FALSE);
2485     curr_bit_offset += 4;
2486     proto_item_set_len(item,((curr_bit_offset-bit_offset)>>3)+1);
2487
2488     return (curr_bit_offset - bit_offset);
2489 }
2490
2491 static guint16
2492 de_rr_gprs_broadcast_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len , gchar *add_string _U_, int string_len _U_)
2493 {
2494     guint32 curr_offset;
2495     gint bit_offset;
2496
2497     curr_offset = offset;
2498     bit_offset = curr_offset << 3;
2499
2500     bit_offset += de_rr_rest_oct_gprs_cell_options(tvb, tree, bit_offset);
2501     bit_offset += de_rr_rest_oct_gprs_power_control_parameters(tvb, tree, bit_offset);
2502     curr_offset += len;
2503
2504     return (curr_offset - offset);
2505 }
2506
2507 /*
2508  * [3] 10.5.2.15 Handover Reference
2509  */
2510 static guint16
2511 de_rr_ho_ref(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2512 {
2513     proto_tree  *subtree;
2514     proto_item  *item;
2515     guint32     curr_offset;
2516
2517     curr_offset = offset;
2518
2519     item =
2520         proto_tree_add_text(tree,
2521                             tvb, curr_offset, 1, "%s",
2522                             gsm_rr_elem_strings[DE_RR_HO_REF].strptr);
2523
2524     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_HO_REF]);
2525
2526     /* Handover reference value */
2527     proto_tree_add_item(subtree, hf_gsm_a_rr_ho_ref_val, tvb, curr_offset, 1, FALSE);
2528
2529     curr_offset = curr_offset + 1;
2530
2531     return(curr_offset - offset);
2532 }
2533 /*
2534  * [3] 10.5.2.16 IA Rest Octets
2535  */
2536
2537 static guint16
2538 de_rr_ia_rest_oct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2539 {
2540     proto_tree  *subtree;
2541     proto_item  *item;
2542     guint32     curr_offset;
2543
2544     len = tvb_length_remaining(tvb,offset);
2545     if (len==0)
2546         return 0;
2547
2548     curr_offset = offset;
2549
2550     item =
2551         proto_tree_add_text(tree,
2552                             tvb, curr_offset, len, "%s",
2553                             gsm_rr_elem_strings[DE_RR_IA_REST_OCT].strptr);
2554
2555     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_IA_REST_OCT]);
2556
2557     proto_tree_add_text(subtree,tvb, curr_offset, len ,"Data(Not decoded)");
2558
2559     curr_offset = curr_offset + len;
2560
2561     return curr_offset-offset;
2562 }
2563
2564 /*
2565  * [3] 10.5.2.17 IAR Rest Octets
2566  */
2567
2568 static guint16
2569 de_rr_iar_rest_oct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2570 {
2571     proto_tree  *subtree;
2572     proto_item  *item;
2573     guint32     curr_offset;
2574
2575     len = 3;
2576     curr_offset = offset;
2577
2578     item =
2579         proto_tree_add_text(tree,
2580                             tvb, curr_offset, 3, "%s",
2581                             gsm_rr_elem_strings[DE_RR_IAR_REST_OCT].strptr);
2582
2583     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_IAR_REST_OCT]);
2584
2585     proto_tree_add_text(subtree,tvb, curr_offset, len ,"Data(Not decoded)");
2586
2587     curr_offset = curr_offset + len;
2588
2589     return curr_offset-offset;
2590 }
2591
2592 /*
2593  * [3] 10.5.2.18 IAX Rest Octets
2594  */
2595 static guint16
2596 de_rr_iax_rest_oct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2597 {
2598     proto_tree  *subtree;
2599     proto_item  *item;
2600     guint32     curr_offset;
2601
2602     len = tvb_length_remaining(tvb,offset);
2603     if (len==0)
2604         return 0;
2605
2606     curr_offset = offset;
2607
2608     item =
2609         proto_tree_add_text(tree,
2610                             tvb, curr_offset, len, "%s",
2611                             gsm_rr_elem_strings[DE_RR_IAX_REST_OCT].strptr);
2612
2613     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_IAX_REST_OCT]);
2614
2615     proto_tree_add_text(subtree,tvb, curr_offset, len ,"Data(Not decoded)");
2616
2617     curr_offset = curr_offset + len;
2618
2619     return curr_offset-offset;
2620 }
2621
2622 /*
2623  * [3] 10.5.2.19 L2 Pseudo Length
2624  */
2625 static guint16
2626 de_rr_l2_pseudo_len(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2627 {
2628     proto_tree  *subtree;
2629     proto_item  *item;
2630     guint32     curr_offset;
2631
2632     curr_offset = offset;
2633
2634     item = proto_tree_add_text(tree,tvb, curr_offset, 1, "%s", gsm_rr_elem_strings[DE_RR_L2_PSEUDO_LEN].strptr);
2635
2636     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_L2_PSEUDO_LEN]);
2637
2638     /* L2 Pseudo Length value */
2639     proto_tree_add_item(subtree, hf_gsm_a_rr_L2_pseudo_len, tvb, curr_offset, 1, FALSE);
2640
2641     curr_offset = curr_offset + 1;
2642
2643     return(curr_offset - offset);
2644 }
2645
2646 /*
2647  * [3] 10.5.2.20 Measurement Results
2648  */
2649 static const true_false_string gsm_a_rr_dtx_vals  = {
2650     "DTX was used",
2651     "DTX was not used"
2652 };
2653
2654
2655 static const true_false_string gsm_a_rr_mv_vals  = {
2656     "The measurement results are not valid",
2657     "The measurement results are valid"
2658 };
2659
2660 static const value_string gsm_a_rr_rxqual_vals [] = {
2661     {0, "BER < 0.2%, Mean value 0.14%"},
2662     {1, "0.2% <= BER < 0.4%, Mean value 0.28%"},
2663     {2, "0.4% <= BER < 0.8%, Mean value 0.57%"},
2664     {3, "0.8% <= BER < 1.6%, Mean value 1.13%"},
2665     {4, "1.6% <= BER < 3.2%, Mean value 2.26%"},
2666     {5, "3.2% <= BER < 6.4%, Mean value 4.53%"},
2667     {6, "6.4% <= BER < 12.8%, Mean value 9.05%"},
2668     {7, "BER > 12.8%, Mean value 18.10%"},
2669     {0, NULL}
2670 };
2671
2672 static const value_string gsm_a_rr_ncell_vals [] = {
2673     {0, "No neighbour cell measurement result"},
2674     {1, "1 neighbour cell measurement result"},
2675     {2, "2 neighbour cell measurement result"},
2676     {3, "3 neighbour cell measurement result"},
2677     {4, "4 neighbour cell measurement result"},
2678     {5, "5 neighbour cell measurement result"},
2679     {6, "6 neighbour cell measurement result"},
2680     {7, "Neighbour cell information not available for serving cell"},
2681     {0, NULL}
2682 };
2683
2684 guint16
2685 de_rr_meas_res(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2686 {
2687     proto_tree  *subtree;
2688     proto_item  *item;
2689     guint32     curr_offset;
2690     gint bit_offset;
2691     guint64 no_ncell_m;
2692
2693     curr_offset = offset;
2694
2695     item =
2696         proto_tree_add_text(tree,
2697                             tvb, curr_offset, 16, "%s",
2698                             gsm_rr_elem_strings[DE_RR_MEAS_RES].strptr);
2699     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_MEAS_RES]);
2700
2701     /* 2nd octet */
2702     /* BA-USED */
2703     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_ba_used, tvb, curr_offset<<3, 1, FALSE);
2704     /* DTX USED */
2705     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_dtx_used, tvb, (curr_offset<<3)+1, 1, FALSE);
2706     /* RXLEV-FULL-SERVING-CELL */
2707     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_rxlev_full_serv_cell, tvb, (curr_offset<<3)+2, 6, FALSE);
2708     curr_offset++;
2709
2710     /* 3rd octet */
2711     /* 3G-BA-USED */
2712     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_3g_ba_used, tvb, curr_offset<<3, 1, FALSE);
2713     /* MEAS-VALID */
2714     proto_tree_add_item(subtree, hf_gsm_a_rr_meas_valid, tvb, curr_offset, 1, FALSE);
2715     /* RXLEV-SUB-SERVING-CELL */
2716     proto_tree_add_item(subtree, hf_gsm_a_rr_rxlev_sub_serv_cell, tvb, curr_offset, 1, FALSE);
2717
2718     curr_offset++;
2719
2720     /* 4th octet */
2721     /* RXQUAL-FULL-SERVING-CELL */
2722     proto_tree_add_bits_item(subtree, hf_gsm_a_rr_rxqual_full_serv_cell, tvb, (curr_offset<<3)+1, 3, FALSE);
2723
2724     /* RXQUAL-SUB-SERVING-CELL */
2725     proto_tree_add_item(subtree, hf_gsm_a_rr_rxqual_sub_serv_cell, tvb, curr_offset, 1, FALSE);
2726     /* NO-NCELL-M */
2727     bit_offset = (curr_offset << 3) + 7;
2728     proto_tree_add_bits_ret_val(subtree, hf_gsm_a_rr_no_ncell_m, tvb, bit_offset, 3, &no_ncell_m, FALSE);
2729     bit_offset += 3;
2730     if (no_ncell_m == 7) /* No neighbour cell information available) */
2731         no_ncell_m = 0;
2732     while (no_ncell_m)
2733     {
2734         proto_tree_add_bits_item(subtree, hf_gsm_a_rr_rxlev_ncell, tvb, bit_offset, 6, FALSE);
2735         bit_offset += 6;
2736         proto_tree_add_bits_item(subtree, hf_gsm_a_rr_bcch_freq_ncell, tvb, bit_offset, 5, FALSE);
2737         bit_offset += 5;
2738         proto_tree_add_bits_item(subtree, hf_gsm_a_rr_bsic_ncell, tvb, bit_offset, 6, FALSE);
2739         bit_offset += 6;
2740         no_ncell_m -= 1;
2741     }
2742
2743     return(len);
2744 }
2745
2746 /*
2747  * [3] 10.5.2.20a GPRS Measurement Results
2748  */
2749 /*
2750  * [3] 10.5.2.21 Mobile Allocation
2751  */
2752 static guint16
2753 de_rr_mob_all(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2754 {
2755     guint32     curr_offset;
2756     proto_item *item;
2757     gint i, j;
2758     guint8 value;
2759
2760     curr_offset = offset;
2761
2762     item = proto_tree_add_text(tree, tvb, curr_offset, len, "Bitmap of increasing ARFCNs included in the Mobile Allocation: ");
2763     for(i=len; i>0; i--)
2764     {
2765         value = tvb_get_guint8(tvb,curr_offset+i-1);
2766         for (j=0; j<8; j++)
2767         {
2768             proto_item_append_text(item,"%d",(value>>j)&0x01);
2769         }
2770     }
2771
2772     curr_offset = curr_offset + len;
2773     return(curr_offset - offset);
2774 }
2775
2776 /*
2777  * [3] 10.5.2.21a Mobile Time Difference
2778  */
2779 static guint16
2780 de_rr_mob_time_diff(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2781 {
2782     guint32     curr_offset;
2783
2784     curr_offset = offset;
2785
2786     proto_tree_add_item(tree, hf_gsm_a_rr_mobile_time_difference, tvb, curr_offset, len, FALSE);
2787
2788     curr_offset = curr_offset + len;
2789     return(curr_offset - offset);
2790
2791 }
2792 /*
2793  * [3] 10.5.2.21aa MultiRate configuration
2794  */
2795 /*      Multirate speech version Octet 3 Bits 8 7 6 */
2796 static const value_string multirate_speech_ver_vals[] = {
2797     { 1, "Adaptive Multirate speech version 1"},
2798     { 2, "Adaptive Multirate speech version 2"},
2799     { 0, NULL }
2800 };
2801 /* Bit 5  NSCB: Noise Suppression Control Bit */
2802 static const value_string NSCB_vals[] = {
2803     { 0, "Noise Suppression can be used (default)"},
2804     { 1, "Noise Suppression shall be turned off"},
2805     { 0, NULL }
2806 };
2807 /* Bit 4 ICMI: Initial Codec Mode Indicator */
2808 static const value_string ICMI_vals[] = {
2809     { 0, "The initial codec mode is defined by the implicit rule provided in 3GPP TS 05.09"},
2810     { 1, "The initial codec mode is defined by the Start Mode field"},
2811     { 0, NULL }
2812 };
2813 /*
2814 Table 10.5.2.21aa.2: Set of adaptive multirate codec modes field (octet 4)
2815 for the Multirate speech version 1
2816 */
2817 static const true_false_string gsm_a_rr_set_of_amr_codec_modes  = {
2818     "is part of the subset",
2819     "is not part of the subset"
2820 };
2821
2822 static const value_string gsm_a_rr_amr_threshold_vals[] = {
2823     {  0, "0.0 dB"},
2824     {  1, "0.5 dB"},
2825     {  2, "1.0 dB"},
2826     {  3, "1.5 dB"},
2827     {  4, "2.0 dB"},
2828     {  5, "2.5 dB"},
2829     {  6, "3.0 dB"},
2830     {  7, "3.5 dB"},
2831     {  8, "4.0 dB"},
2832     {  9, "4.5 dB"},
2833     { 10, "5.0 dB"},
2834     { 11, "5.5 dB"},
2835     { 12, "6.0 dB"},
2836     { 13, "6.5 dB"},
2837     { 14, "7.0 dB"},
2838     { 15, "7.5 dB"},
2839     { 16, "8.0 dB"},
2840     { 17, "8.5 dB"},
2841     { 18, "9.0 dB"},
2842     { 19, "9.5 dB"},
2843     { 20, "10.0 dB"},
2844     { 21, "10.5 dB"},
2845     { 22, "11.0 dB"},
2846     { 23, "11.5 dB"},
2847     { 24, "12.0 dB"},
2848     { 25, "12.5 dB"},
2849     { 26, "13.0 dB"},
2850     { 27, "13.5 dB"},
2851     { 28, "14.0 dB"},
2852     { 29, "14.5 dB"},
2853     { 30, "15.0 dB"},
2854     { 31, "15.5 dB"},
2855     { 32, "16.0 dB"},
2856     { 33, "16.5 dB"},
2857     { 34, "17.0 dB"},
2858     { 35, "17.5 dB"},
2859     { 36, "18.0 dB"},
2860     { 37, "18.5 dB"},
2861     { 38, "19.0 dB"},
2862     { 39, "19.5 dB"},
2863     { 40, "20.0 dB"},
2864     { 41, "20.5 dB"},
2865     { 42, "21.0 dB"},
2866     { 43, "21.5 dB"},
2867     { 44, "22.0 dB"},
2868     { 45, "22.5 dB"},
2869     { 46, "23.0 dB"},
2870     { 47, "23.5 dB"},
2871     { 48, "24.0 dB"},
2872     { 49, "24.5 dB"},
2873     { 50, "25.0 dB"},
2874     { 51, "25.5 dB"},
2875     { 52, "26.0 dB"},
2876     { 53, "26.5 dB"},
2877     { 54, "27.0 dB"},
2878     { 55, "27.5 dB"},
2879     { 56, "28.0 dB"},
2880     { 57, "28.5 dB"},
2881     { 58, "29.0 dB"},
2882     { 59, "29.5 dB"},
2883     { 60, "30.0 dB"},
2884     { 61, "30.5 dB"},
2885     { 62, "31.0 dB"},
2886     { 63, "31.5 dB"},
2887     { 0, NULL }
2888 };
2889
2890 static const value_string gsm_a_rr_amr_hysteresis_vals[] = {
2891     {  0, "0.0 dB"},
2892     {  1, "0.5 dB"},
2893     {  2, "1.0 dB"},
2894     {  3, "1.5 dB"},
2895     {  4, "2.0 dB"},
2896     {  5, "2.5 dB"},
2897     {  6, "3.0 dB"},
2898     {  7, "3.5 dB"},
2899     {  8, "4.0 dB"},
2900     {  9, "4.5 dB"},
2901     { 10, "5.0 dB"},
2902     { 11, "5.5 dB"},
2903     { 12, "6.0 dB"},
2904     { 13, "6.5 dB"},
2905     { 14, "7.0 dB"},
2906     { 15, "7.5 dB"},
2907     { 0, NULL }
2908 };
2909
2910 guint16
2911 de_rr_multirate_conf(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2912 {
2913     guint32     curr_offset;
2914     guint8 oct;
2915     gint bit_offset, remaining_length, nb_of_params;
2916
2917     curr_offset = offset;
2918
2919     proto_tree_add_item(tree, hf_gsm_a_rr_multirate_speech_ver, tvb, curr_offset, 1, FALSE);
2920     proto_tree_add_item(tree, hf_gsm_a_rr_NCSB, tvb, curr_offset, 1, FALSE);
2921     proto_tree_add_item(tree, hf_gsm_a_rr_ICMI, tvb, curr_offset, 1, FALSE);
2922     /* The initial codec mode is coded as in 3GPP TS 45.009 */
2923     proto_tree_add_item(tree, hf_gsm_a_rr_start_mode, tvb, curr_offset, 1, FALSE);
2924     oct = ( tvb_get_guint8(tvb,curr_offset) &0xe0 ) >> 5;
2925     curr_offset++;
2926     switch ( oct){
2927     case 1:
2928         /* Adaptive Multirate speech version 1 */
2929         /* Set of AMR codec modes */
2930         proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v1_b8, tvb, curr_offset, 1, FALSE);
2931         proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v1_b7, tvb, curr_offset, 1, FALSE);
2932         proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v1_b6, tvb, curr_offset, 1, FALSE);
2933         proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v1_b5, tvb, curr_offset, 1, FALSE);
2934         proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v1_b4, tvb, curr_offset, 1, FALSE);
2935         proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v1_b3, tvb, curr_offset, 1, FALSE);
2936         proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v1_b2, tvb, curr_offset, 1, FALSE);
2937         proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v1_b1, tvb, curr_offset, 1, FALSE);
2938         curr_offset++;
2939
2940         remaining_length = len-2;
2941         break;
2942     case 2:
2943         /* Adaptive Multirate speech version 2 */
2944         proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v2_b5, tvb, curr_offset, 1, FALSE);
2945         proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v2_b4, tvb, curr_offset, 1, FALSE);
2946         proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v2_b3, tvb, curr_offset, 1, FALSE);
2947         proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v2_b2, tvb, curr_offset, 1, FALSE);
2948         proto_tree_add_item(tree, hf_gsm_a_rr_set_of_amr_codec_modes_v2_b1, tvb, curr_offset, 1, FALSE);
2949         curr_offset++;
2950
2951         remaining_length = len-2;
2952         break;
2953     default:
2954         proto_tree_add_text(tree,tvb,offset,1,"Unknown version");
2955         proto_tree_add_text(tree,tvb, curr_offset, len-1 ,"Data(Not decoded)");
2956         remaining_length = 0;
2957         break;
2958     }
2959
2960     if (remaining_length)
2961     {
2962         bit_offset = (curr_offset<<3) + 2;
2963         nb_of_params = remaining_length - 1;
2964         while (nb_of_params)
2965         {
2966             proto_tree_add_bits_item(tree, hf_gsm_a_rr_amr_threshold, tvb, bit_offset, 6, FALSE);
2967             bit_offset += 6;
2968             proto_tree_add_bits_item(tree, hf_gsm_a_rr_amr_hysteresis, tvb, bit_offset, 4, FALSE);
2969             bit_offset += 4;
2970             nb_of_params -= 1;
2971         }
2972     }
2973
2974     curr_offset = offset + len;
2975     return(curr_offset - offset);
2976
2977 }
2978 /*
2979  * [3] 10.5.2.21b Multislot Allocation
2980  */
2981 static guint16
2982 de_rr_mult_all(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2983 {
2984     guint32     curr_offset;
2985
2986     curr_offset = offset;
2987
2988     proto_tree_add_text(tree,tvb, curr_offset, len ,"Data(Not decoded)");
2989
2990     curr_offset = curr_offset + len;
2991     return(curr_offset - offset);
2992
2993 }
2994 /*
2995  * [3] 10.5.2.21c NC mode
2996  */
2997
2998  /*
2999  * [3] 10.5.2.22 Neighbour Cell Description
3000  */
3001 static const value_string gsm_a_rr_ext_ind_vals[] = {
3002     { 0, "The information element carries the complete BA"},
3003     { 1, "The information element carries only a part of the BA"},
3004     { 0, NULL }
3005 };
3006 static guint16
3007 de_rr_neigh_cell_desc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3008 {
3009     guint32     curr_offset;
3010
3011     curr_offset = offset;
3012
3013     proto_tree_add_item(tree, hf_gsm_a_rr_ext_ind, tvb, curr_offset, 1, FALSE);
3014     proto_tree_add_bits_item(tree, hf_gsm_a_rr_ba_ind, tvb, (curr_offset<<3)+3, 1, FALSE);
3015
3016     return dissect_arfcn_list(tvb, tree, offset, 16, add_string, string_len);
3017 }
3018
3019  /*
3020  * [3] 10.5.2.22a Neighbour Cell Description 2
3021  */
3022 static guint16
3023 de_rr_neigh_cell_desc2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3024 {
3025     guint32     curr_offset;
3026
3027     curr_offset = offset;
3028
3029     proto_tree_add_bits_item(tree, hf_gsm_a_rr_multiband_reporting, tvb, (curr_offset<<3)+1, 2, FALSE);
3030     proto_tree_add_bits_item(tree, hf_gsm_a_rr_ba_ind, tvb, (curr_offset<<3)+3, 1, FALSE);
3031
3032     return dissect_arfcn_list2(tvb, tree, offset, 16, add_string, string_len);
3033 }
3034
3035 /*
3036  * [3] 10.5.2.22b (void)
3037  * [3] 10.5.2.22c NT/N Rest Octets
3038  */
3039
3040 /*
3041  * [3] 10.5.2.23 P1 Rest Octets
3042  */
3043 static guint16
3044 de_rr_p1_rest_oct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3045 {
3046     proto_tree *subtree;
3047     proto_item *item, *item2;
3048     guint32 curr_offset, value;
3049     gint bit_offset, bit_offset_sav, i;
3050
3051     curr_offset = offset;
3052     bit_offset = curr_offset << 3;
3053     len = tvb_length_remaining(tvb,offset);
3054
3055     item = proto_tree_add_text(tree, tvb, curr_offset, len, "%s",
3056                                gsm_rr_elem_strings[DE_RR_P1_REST_OCT].strptr);
3057
3058     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_P1_REST_OCT]);
3059
3060     if (gsm_a_rr_is_bit_high(tvb,bit_offset) == TRUE)
3061     {
3062         bit_offset += 1;
3063         proto_tree_add_bits_item(subtree, hf_gsm_a_rr_nln_pch, tvb, bit_offset, 2, FALSE);
3064         bit_offset += 2;
3065         proto_tree_add_bits_item(subtree, hf_gsm_a_rr_nln_status_pch, tvb, bit_offset, 1, FALSE);
3066         bit_offset += 1;
3067     }
3068     else
3069         bit_offset += 1;
3070     for (i=1; i<=2; i++)
3071     {
3072         if (gsm_a_rr_is_bit_high(tvb,bit_offset) == TRUE)
3073         {
3074             bit_offset += 1;
3075             item2 = proto_tree_add_bits_item(subtree, hf_gsm_a_call_prio, tvb, bit_offset, 3, FALSE);
3076             bit_offset += 3;
3077             proto_item_append_text(item2, " for Mobile Identity %d", i);
3078         }
3079         else
3080             bit_offset += 1;
3081     }
3082     if (gsm_a_rr_is_bit_high(tvb,bit_offset) == TRUE)
3083     { /* Group Call Information */
3084         bit_offset += 1;
3085         bit_offset_sav = bit_offset;
3086         bit_offset += 36;
3087         if (tvb_get_bits8(tvb,bit_offset,1))
3088         { /* Group Channel Description */
3089             bit_offset += 24+1;
3090             if (tvb_get_bits8(tvb,bit_offset,1))
3091             { /* Hopping case */
3092                 bit_offset += 1;
3093                 if (tvb_get_bits8(tvb,bit_offset,1))
3094                 {
3095                     bit_offset += 64+1;
3096                 }
3097                 else
3098                 {
3099                     bit_offset += 1;
3100                     value = tvb_get_bits8(tvb,bit_offset,8);
3101                     bit_offset += 8 + (value<<3);
3102                 }
3103             }
3104             else
3105                 bit_offset += 1;
3106         }
3107         else
3108             bit_offset += 1;
3109         proto_tree_add_text(subtree,tvb, bit_offset_sav>>3, (bit_offset-bit_offset_sav)>>3,"Group Call Information: Data(Not decoded)");
3110     }
3111     else
3112         bit_offset += 1;
3113     for (i=1; i<=2; i++)
3114     {
3115         item2 = proto_tree_add_text(subtree,tvb, bit_offset>>3, 1, "Packet Page Indication %d: ", i);
3116         if (gsm_a_rr_is_bit_high(tvb,bit_offset) == TRUE)
3117             proto_item_append_text(item2, "Packet paging procedure");
3118         else
3119             proto_item_append_text(item2, "Paging procedure for RR connection establishment");
3120         bit_offset += 1;
3121     }
3122     if (((curr_offset + len)<<3) - bit_offset > 0)
3123     {
3124         /* There is still room left in the Rest Octets IE */
3125         if (gsm_a_rr_is_bit_high(tvb,bit_offset) == TRUE)
3126         { /* Additions in release 6 */
3127             bit_offset += 1;
3128             proto_tree_add_text(subtree, tvb, bit_offset>>3, -1,"Additions in Release 6: Data(Not decoded)");
3129         }
3130         else
3131             bit_offset += 1;
3132     }
3133
3134     curr_offset = curr_offset + len;
3135
3136     return (curr_offset - offset);
3137 }
3138
3139 /*
3140  * [3] 10.5.2.24 P2 Rest Octets
3141  */
3142 static guint16
3143 de_rr_p2_rest_oct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3144
3145 {
3146     proto_tree *subtree;
3147     proto_item *item, *item2;
3148     guint32 curr_offset;
3149     gint bit_offset, i;
3150
3151     curr_offset = offset;
3152     bit_offset = curr_offset << 3;
3153     len = tvb_length_remaining(tvb,offset);
3154
3155     item = proto_tree_add_text(tree, tvb, curr_offset, len, "%s",
3156                                gsm_rr_elem_strings[DE_RR_P2_REST_OCT].strptr);
3157
3158     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_P2_REST_OCT]);
3159
3160     if (gsm_a_rr_is_bit_high(tvb,bit_offset) == TRUE)
3161     {
3162         bit_offset += 1;
3163         proto_tree_add_bits_item(subtree, hf_gsm_a_rr_chnl_needed_ch3, tvb, bit_offset, 2, FALSE);
3164         bit_offset += 2;
3165     }
3166     else
3167         bit_offset += 1;
3168     if (gsm_a_rr_is_bit_high(tvb,bit_offset) == TRUE)
3169     {
3170         bit_offset += 1;
3171         proto_tree_add_bits_item(subtree, hf_gsm_a_rr_nln_pch, tvb, bit_offset, 2, FALSE);
3172         bit_offset += 2;
3173         proto_tree_add_bits_item(subtree, hf_gsm_a_rr_nln_status_pch, tvb, bit_offset, 1, FALSE);
3174         bit_offset += 1;
3175     }
3176     else
3177         bit_offset += 1;
3178     for (i=1; i<=3; i++)
3179     {
3180         if (gsm_a_rr_is_bit_high(tvb,bit_offset) == TRUE)
3181         {
3182             bit_offset += 1;
3183             item2 = proto_tree_add_bits_item(subtree, hf_gsm_a_call_prio, tvb, bit_offset, 3, FALSE);
3184             bit_offset += 3;
3185             proto_item_append_text(item2, " for Mobile Identity %d", i);
3186         }
3187         else
3188             bit_offset += 1;
3189     }
3190     item2 = proto_tree_add_text(subtree,tvb, bit_offset>>3, 1, "Packet Page Indication 3: ");
3191     if (gsm_a_rr_is_bit_high(tvb,bit_offset) == TRUE)
3192         proto_item_append_text(item2, "Packet paging procedure");
3193     else
3194         proto_item_append_text(item2, "Paging procedure for RR connection establishment");
3195     bit_offset += 1;
3196     if (((curr_offset + len)<<3) - bit_offset > 0)
3197     {
3198         /* There is still room left in the Rest Octets IE */
3199         if (gsm_a_rr_is_bit_high(tvb,bit_offset) == TRUE)
3200         { /* Additions in release 6 */
3201             bit_offset += 1;
3202             proto_tree_add_text(subtree, tvb, bit_offset>>3, -1,"Additions in Release 6: Data(Not decoded)");
3203         }
3204         else
3205             bit_offset += 1;
3206     }
3207
3208     curr_offset = curr_offset + len;
3209
3210     return (curr_offset - offset);
3211 }
3212
3213 /*
3214  * [3] 10.5.2.25 P3 Rest Octets
3215  */
3216 static guint16
3217 de_rr_p3_rest_oct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3218 {
3219     proto_tree *subtree;
3220     proto_item *item, *item2;
3221     guint32 curr_offset;
3222     gint bit_offset, i;
3223
3224     curr_offset = offset;
3225     bit_offset = curr_offset << 3;
3226     len = 3;
3227
3228     item = proto_tree_add_text(tree, tvb, curr_offset, len, "%s",
3229                                gsm_rr_elem_strings[DE_RR_P3_REST_OCT].strptr);
3230
3231     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_P3_REST_OCT]);
3232
3233     if (gsm_a_rr_is_bit_high(tvb,bit_offset) == TRUE)
3234     {
3235         bit_offset += 1;
3236         proto_tree_add_bits_item(subtree, hf_gsm_a_rr_chnl_needed_ch3, tvb, bit_offset, 2, FALSE);
3237         bit_offset += 2;
3238         proto_tree_add_bits_item(subtree, hf_gsm_a_rr_chnl_needed_ch4, tvb, bit_offset, 2, FALSE);
3239         bit_offset += 2;
3240     }
3241     else
3242         bit_offset += 1;
3243     if (gsm_a_rr_is_bit_high(tvb,bit_offset) == TRUE)
3244     {
3245         bit_offset += 1;
3246         proto_tree_add_bits_item(subtree, hf_gsm_a_rr_nln_pch, tvb, bit_offset, 2, FALSE);
3247         bit_offset += 2;
3248         proto_tree_add_bits_item(subtree, hf_gsm_a_rr_nln_status_pch, tvb, bit_offset, 1, FALSE);
3249         bit_offset += 1;
3250     }
3251     else
3252         bit_offset += 1;
3253     for (i=1; i<=4; i++)
3254     {
3255         if (gsm_a_rr_is_bit_high(tvb,bit_offset) == TRUE)
3256         {
3257             bit_offset += 1;
3258             item2 = proto_tree_add_bits_item(subtree, hf_gsm_a_call_prio, tvb, bit_offset, 3, FALSE);
3259             bit_offset += 3;
3260             proto_item_append_text(item2, " for Mobile Identity %d", i);
3261         }
3262         else
3263             bit_offset += 1;
3264     }
3265
3266     curr_offset = curr_offset + len;
3267
3268     return (curr_offset - offset);
3269 }
3270
3271 /*
3272  * [3] 10.5.2.25a Packet Channel Description C V 3
3273  */
3274 static guint16
3275 de_rr_packet_ch_desc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3276 {
3277     guint32     curr_offset;
3278     guint8      oct8;
3279     guint16     arfcn, hsn, maio;
3280     proto_tree  *subtree;
3281     proto_item  *item;
3282     const gchar *str;
3283
3284     curr_offset = offset;
3285
3286     item = proto_tree_add_text(tree,tvb,curr_offset,3, "%s", gsm_rr_elem_strings[DE_RR_PACKET_CH_DESC].strptr);
3287     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_PACKET_CH_DESC]);
3288
3289     /* Octet 2 */
3290     oct8 = tvb_get_guint8(tvb, curr_offset);
3291     /* Channel Type */
3292     str = "Spare bits (ignored by receiver)";
3293     other_decode_bitfield_value(a_bigbuf, oct8, 0xf8, 8);
3294     proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = %s",a_bigbuf,str);
3295     /* TN */
3296     other_decode_bitfield_value(a_bigbuf, oct8, 0x07, 8);
3297     proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Timeslot: %d",a_bigbuf,(oct8 & 0x07));
3298
3299     curr_offset +=1;
3300
3301     /* Octet 3 */
3302     oct8 = tvb_get_guint8(tvb, curr_offset);
3303     other_decode_bitfield_value(a_bigbuf, oct8, 0xe0, 8);
3304     proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Training Sequence: %d",a_bigbuf,((oct8 & 0xe0)>>5));
3305
3306     if ((oct8 & 0x10) == 0x10)
3307     {
3308         /* Hopping sequence */
3309         maio = ((oct8 & 0x0f)<<2) | ((tvb_get_guint8(tvb,curr_offset+1) & 0xc0) >> 6);
3310         hsn = (tvb_get_guint8(tvb,curr_offset+1) & 0x3f);
3311         str = "Yes";
3312
3313         other_decode_bitfield_value(a_bigbuf, oct8, 0x10, 8);
3314         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Hopping channel: %s",a_bigbuf,str);
3315         proto_tree_add_text(subtree,tvb, curr_offset, 2,"Hopping channel: MAIO %d",maio);
3316         proto_tree_add_text(subtree,tvb, curr_offset, 2,"Hopping channel: HSN %d",hsn);
3317     }
3318     else
3319     {
3320         /* single ARFCN */
3321         arfcn = ((oct8 & 0x03) << 8) | tvb_get_guint8(tvb,curr_offset+1);
3322         str = "No";
3323         other_decode_bitfield_value(a_bigbuf, oct8, 0x10, 8);
3324         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Hopping channel: %s",a_bigbuf,str);
3325         other_decode_bitfield_value(a_bigbuf, oct8, 0x0c, 8);
3326         proto_tree_add_text(subtree,tvb, curr_offset, 1,"%s = Spare",a_bigbuf);
3327         proto_tree_add_text(subtree,tvb, curr_offset, 2,"Single channel : ARFCN %d",arfcn);
3328     }
3329
3330     curr_offset = curr_offset + 2;
3331     return(curr_offset - offset);
3332
3333 }
3334 /*
3335  * [3] 10.5.2.25b Dedicated mode or TBF
3336  */
3337
3338 static const value_string gsm_a_rr_dedicated_mode_or_tbf_vals[] = {
3339     { 0, "This message assigns a dedicated mode resource"},
3340     { 1, "This message assigns an uplink TBF or is the second message of two in a two-message assignment of an uplink or downlink TBF"},
3341     { 2, "Not used"},
3342     { 3, "This message assigns a downlink TBF to the mobile station identified in the IA Rest Octets IE"},
3343     { 4, "Not used"},
3344     { 5, "This message is the first message of two in a two-message assignment of an uplink TBF"},
3345     { 6, "Not used"},
3346     { 7, "This message is the first message of two in a two-message assignment of a downlink TBF to the mobile station identified in the IA Rest Octets IE"},
3347     { 0, NULL }
3348 };
3349 static guint16
3350 de_rr_ded_mod_or_tbf(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3351 {
3352     proto_tree  *subtree;
3353     proto_item  *item;
3354     guint32     curr_offset;
3355
3356     curr_offset = offset;
3357
3358     item =
3359         proto_tree_add_text(tree,
3360                             tvb, curr_offset, 1, "%s",
3361                             gsm_rr_elem_strings[DE_RR_DED_MOD_OR_TBF].strptr);
3362
3363     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_DED_MOD_OR_TBF]);
3364
3365     proto_tree_add_item(subtree, hf_gsm_a_rr_dedicated_mode_or_tbf, tvb, curr_offset, 1, FALSE);
3366
3367     curr_offset += 1;
3368
3369     return(curr_offset - offset);
3370 }
3371 /*
3372  * [3] 10.5.2.25c RR Packet Uplink Assignment
3373  * [3] 10.5.2.25d RR Packet Downlink Assignment
3374  */
3375 /*
3376  * [3] 10.5.2.26 Page Mode
3377  */
3378
3379 static const value_string gsm_a_rr_page_mode_vals[] = {
3380     { 0, "Normal paging"},
3381     { 1, "Extended paging"},
3382     { 2, "Paging reorganization"},
3383     { 3, "Same as before"},
3384     { 0, NULL }
3385 };
3386 static guint16
3387 de_rr_page_mode(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3388 {
3389     proto_tree  *subtree;
3390     proto_item  *item;
3391     guint32     curr_offset;
3392
3393     curr_offset = offset;
3394
3395     item =
3396         proto_tree_add_text(tree,
3397                             tvb, curr_offset, 1, "%s",
3398                             gsm_rr_elem_strings[DE_RR_PAGE_MODE].strptr);
3399
3400     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_PAGE_MODE]);
3401
3402     proto_tree_add_item(subtree, hf_gsm_a_rr_page_mode, tvb, curr_offset, 1, FALSE);
3403
3404     curr_offset += 1;
3405
3406     return(curr_offset - offset);
3407 }
3408 /*
3409  * [3] 10.5.2.26a (void)
3410  * [3] 10.5.2.26b (void)
3411  * [3] 10.5.2.26c (void)
3412  * [3] 10.5.2.26d (void)
3413  */
3414 /*
3415  * [3] 10.5.2.27 NCC Permitted
3416  */
3417 static guint16
3418 de_rr_ncc_perm(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3419 {
3420     proto_tree  *subtree;
3421     proto_item  *item;
3422     guint32     curr_offset;
3423
3424     curr_offset = offset;
3425
3426     item = proto_tree_add_text(tree, tvb, curr_offset, 1, "%s",
3427                                gsm_rr_elem_strings[DE_RR_NCC_PERM].strptr);
3428
3429     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_NCC_PERM]);
3430
3431     proto_tree_add_item(subtree, hf_gsm_a_rr_ncc_permitted, tvb, curr_offset, 1, FALSE);
3432
3433     curr_offset = curr_offset + 1;
3434
3435     return(curr_offset - offset);
3436 }
3437 /*
3438  * [3] 10.5.2.28 Power Command
3439  *
3440  *
3441  * ATC (Access Type Control) (octet 2)Bit 8
3442  * 0    Sending of Handover access is mandatory
3443  * 1    Sending of Handover access is optional
3444  */
3445 static const true_false_string gsm_a_rr_pow_cmd_atc_value  = {
3446     "Sending of Handover access is optional",
3447     "Sending of Handover access is mandatory"
3448 };
3449 /*
3450  *  The EPC mode field (octet 2) indicates whether the assigned channel(s)
3451  *  shall be in enhanced power control (EPC) mode. It is only valid for channels
3452  *  on which EPC may be used. It is coded as follows:
3453 */
3454 static const true_false_string gsm_a_rr_pow_cmd_epc_value  = {
3455     "Channel(s) in EPC mode",
3456     "Channel(s) not in EPC mode"
3457 };
3458 /*
3459  * FPC_EPC (octet 2)
3460  * The FPC_EPC field (octet 2) has different interpretation depending
3461  *              on the channel mode     of the assigned channel (s) and the value
3462  *              of the EPC mode field.
3463  * If the channel mode is such that fast power control (FPC) may be
3464  *              used, the FPC_EPC field indicates whether Fast Measurement
3465  *              Reporting and Power Control mechanism is used.
3466  *              It is coded as follows:
3467  * Value 0      FPC not in use
3468  *         1    FPC in use
3469  * If the channel mode is such that EPC may be used and the EPC mode
3470  *              field indicates that the channel is in EPC mode, the FPC_EPC
3471  *              field indicates whether EPC shall be used for uplink power control.
3472  * It is coded as follows:
3473  * Value 0      EPC not in use for uplink power control
3474  *               1      EPC in use for uplink power control
3475  *
3476  */
3477 static const true_false_string gsm_a_rr_pow_cmd_fpcepc_value  = {
3478     "FPC in use/EPC in use for uplink power control",
3479     "FPC not in use/C not in use for uplink power control"
3480 };
3481
3482 /*
3483  * Power level (octet 2)The power level field is coded as the binaryRepresentation
3484  * of the "power control level", see 3GPP TS 3GPP TS 45.005. This value shall be used
3485  * by the mobile station According to 3GPP TS 45.008.Range: 0 to 31.
3486  */
3487
3488 static guint16
3489 de_rr_pow_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3490 {
3491     proto_tree  *subtree;
3492     proto_item  *item;
3493     guint32     curr_offset;
3494
3495     curr_offset = offset;
3496
3497     item =
3498         proto_tree_add_text(tree,
3499                             tvb, curr_offset, 1, "%s",
3500                             gsm_rr_elem_strings[DE_RR_POW_CMD].strptr);
3501
3502     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_POW_CMD]);
3503
3504     proto_tree_add_item(subtree, hf_gsm_a_b8spare, tvb, curr_offset, 1, FALSE);
3505     /*EPC mode */
3506     proto_tree_add_item(subtree, hf_gsm_a_rr_pow_cmd_epc, tvb, curr_offset, 1, FALSE);
3507     /*FPC_EPC*/
3508     proto_tree_add_item(subtree, hf_gsm_a_rr_pow_cmd_fpcepc, tvb, curr_offset, 1, FALSE);
3509     /*POWER LEVEL*/
3510     proto_tree_add_item(subtree, hf_gsm_a_rr_pow_cmd_powlev, tvb, curr_offset, 1, FALSE);
3511
3512     curr_offset = curr_offset + 1;
3513
3514     return(curr_offset - offset);
3515 }
3516
3517 /*
3518  * [3] 10.5.2.28a Power Command and access type
3519  */
3520 static guint16
3521 de_rr_pow_cmd_and_acc_type(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3522 {
3523     proto_tree  *subtree;
3524     proto_item  *item;
3525     guint32     curr_offset;
3526
3527     curr_offset = offset;
3528
3529     item =
3530         proto_tree_add_text(tree,
3531                             tvb, curr_offset, 1, "%s",
3532                             gsm_rr_elem_strings[DE_RR_POW_CMD_AND_ACC_TYPE].strptr);
3533
3534     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_POW_CMD_AND_ACC_TYPE]);
3535
3536     /*ATC */
3537     proto_tree_add_item(subtree, hf_gsm_a_rr_pow_cmd_atc, tvb, curr_offset, 1, FALSE);
3538     /*EPC mode */
3539     proto_tree_add_item(subtree, hf_gsm_a_rr_pow_cmd_epc, tvb, curr_offset, 1, FALSE);
3540     /*FPC_EPC*/
3541     proto_tree_add_item(subtree, hf_gsm_a_rr_pow_cmd_fpcepc, tvb, curr_offset, 1, FALSE);
3542     /*POWER LEVEL*/
3543     proto_tree_add_item(subtree, hf_gsm_a_rr_pow_cmd_powlev, tvb, curr_offset, 1, FALSE);
3544
3545     curr_offset = curr_offset + 1;
3546
3547     return(curr_offset - offset);
3548 }
3549 /*
3550  * [3] 10.5.2.29 RACH Control Parameters
3551  */
3552
3553 static const value_string gsm_a_rr_max_retrans_vals[] = {
3554     {  0, "Maximum 1 retransmission"},
3555     {  1, "Maximum 2 retransmissions"},
3556     {  2, "Maximum 4 retransmissions"},
3557     {  3, "Maximum 7 retransmissions"},
3558     {  0, NULL }
3559 };
3560
3561 static const value_string gsm_a_rr_tx_integer_vals[] = {
3562     {  0, "3 slots used to spread transmission"},
3563     {  1, "4 slots used to spread transmission"},
3564     {  2, "5 slots used to spread transmission"},
3565     {  3, "6 slots used to spread transmission"},
3566     {  4, "7 slots used to spread transmission"},
3567     {  5, "8 slots used to spread transmission"},
3568     {  6, "9 slots used to spread transmission"},
3569     {  7, "10 slots used to spread transmission"},
3570     {  8, "11 slots used to spread transmission"},
3571     {  9, "12 slots used to spread transmission"},
3572     { 10, "14 slots used to spread transmission"},
3573     { 11, "16 slots used to spread transmission"},
3574     { 12, "20 slots used to spread transmission"},
3575     { 13, "25 slots used to spread transmission"},
3576     { 14, "32 slots used to spread transmission"},
3577     { 15, "50 slots used to spread transmission"},
3578     {  0, NULL }
3579 };
3580 static const value_string gsm_a_rr_cell_barr_access_vals[] = {
3581     {  0, "The cell is not barred"},
3582     {  1, "The cell is barred"},
3583     {  0, NULL }
3584 };
3585 static const value_string gsm_a_rr_re_vals[] = {
3586     {  0, "Call Reestablishment allowed in the cell"},
3587     {  1, "Call Reestablishment not allowed in the cell"},
3588     {  0, NULL }
3589 };
3590
3591 static guint16
3592 de_rr_rach_ctrl_param(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3593 {
3594     proto_tree  *subtree;
3595     proto_item  *item;
3596     guint32     curr_offset;
3597
3598     curr_offset = offset;
3599
3600     item = proto_tree_add_text(tree, tvb, curr_offset, 3, "%s",
3601                                gsm_rr_elem_strings[DE_RR_RACH_CTRL_PARAM].strptr);
3602
3603     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_RACH_CTRL_PARAM]);
3604
3605     proto_tree_add_item(subtree, hf_gsm_a_rr_max_retrans, tvb, curr_offset, 1, FALSE);
3606     proto_tree_add_item(subtree, hf_gsm_a_rr_tx_integer, tvb, curr_offset, 1, FALSE);
3607     proto_tree_add_item(subtree, hf_gsm_a_rr_cell_barr_access, tvb, curr_offset, 1, FALSE);
3608     proto_tree_add_item(subtree, hf_gsm_a_rr_re, tvb, curr_offset, 1, FALSE);
3609     curr_offset = curr_offset + 1;
3610
3611     proto_tree_add_item(subtree, hf_gsm_a_rr_acc, tvb, curr_offset, 2, FALSE);
3612
3613     curr_offset = curr_offset + 2;
3614
3615     return(curr_offset - offset);
3616 }
3617 /*
3618  * [3] 10.5.2.30 Request Reference M V 3
3619  */
3620 static guint16 reduced_frame_number(guint16 fn)
3621 {
3622     /* great care needed with signed/unsigned - -1 in unsigned is 0xffff, which mod(26) is not what you think !!! */
3623     gint16      t2, t3, t;
3624     guint16     frame, t1;
3625
3626     t1 = (fn >> 11) & 0x1f;
3627     t2 = (fn >> 0) & 0x1f;
3628     t3 = (fn >> 5) & 0x3f;
3629
3630     t = (t3-t2)%26;
3631     if (t<0)
3632         t += 26;
3633
3634     frame = 51*(unsigned)t+(unsigned)t3+51*26*t1;
3635
3636     return frame;
3637 }
3638
3639 static guint16
3640 de_rr_req_ref(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3641 {
3642     proto_tree  *subtree;
3643     proto_item  *item;
3644     guint32     curr_offset;
3645     guint16     rfn;
3646     guint16     fn;
3647
3648     curr_offset = offset;
3649
3650     item =
3651         proto_tree_add_text(tree,
3652                             tvb, curr_offset, 3, "%s",
3653                             gsm_rr_elem_strings[DE_RR_REQ_REF].strptr);
3654
3655     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_REQ_REF]);
3656
3657     proto_tree_add_item(subtree, hf_gsm_a_rr_ra, tvb, curr_offset, 1, FALSE);
3658     curr_offset++;
3659     fn = tvb_get_ntohs(tvb,curr_offset);
3660     rfn = reduced_frame_number(fn);
3661     proto_tree_add_item(subtree, hf_gsm_a_rr_T1prim, tvb, curr_offset, 1, FALSE);
3662     proto_tree_add_item(subtree, hf_gsm_a_rr_T3, tvb, curr_offset, 2, FALSE);
3663     curr_offset++;
3664     proto_tree_add_item(subtree, hf_gsm_a_rr_T2, tvb, curr_offset, 1, FALSE);
3665     curr_offset++;
3666     item = proto_tree_add_uint(subtree, hf_gsm_a_rr_rfn, tvb, curr_offset-2, 2, rfn);
3667     PROTO_ITEM_SET_GENERATED(item);
3668
3669     return(curr_offset - offset);
3670 }
3671 /*
3672  * [3] 10.5.2.31
3673  */
3674 guint16
3675 de_rr_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3676 {
3677     guint32     curr_offset;
3678
3679     curr_offset = offset;
3680
3681     proto_tree_add_item(tree, hf_gsm_a_rr_RR_cause, tvb, curr_offset, 1, FALSE);
3682
3683     curr_offset++;
3684
3685     return(curr_offset - offset);
3686 }
3687
3688 /*
3689  * [3] 10.5.2.32 SI 1 Rest Octets
3690  */
3691 static const value_string gsm_a_rr_nch_position_vals[] = {
3692     { 0, "No of blocks = 1 and Number of first block = 0"},
3693     { 1, "No of blocks = 1 and Number of first block = 1"},
3694     { 2, "No of blocks = 1 and Number of first block = 2"},
3695     { 3, "No of blocks = 1 and Number of first block = 3"},
3696     { 4, "No of blocks = 1 and Number of first block = 4"},
3697     { 5, "No of blocks = 1 and Number of first block = 5"},
3698     { 6, "No of blocks = 1 and Number of first block = 6"},
3699     { 7, "No of blocks = 1 and Number of first block = 0"},
3700     { 8, "No of blocks = 2 and Number of first block = 1"},
3701     { 9, "No of blocks = 2 and Number of first block = 2"},
3702     {10, "No of blocks = 2 and Number of first block = 3"},
3703     {11, "No of blocks = 2 and Number of first block = 4"},
3704     {12, "No of blocks = 2 and Number of first block = 5"},
3705     {13, "No of blocks = 3 and Number of first block = 0"},
3706     {14, "No of blocks = 3 and Number of first block = 1"},
3707     {15, "No of blocks = 3 and Number of first block = 2"},
3708     {16, "No of blocks = 3 and Number of first block = 3"},
3709     {17, "No of blocks = 3 and Number of first block = 4"},
3710     {18, "No of blocks = 4 and Number of first block = 0"},
3711     {19, "No of blocks = 4 and Number of first block = 1"},
3712     {20, "No of blocks = 4 and Number of first block = 2"},
3713     {21, "No of blocks = 4 and Number of first block = 3"},
3714     {22, "No of blocks = 5 and Number of first block = 0"},
3715     {23, "No of blocks = 5 and Number of first block = 1"},
3716     {24, "No of blocks = 5 and Number of first block = 2"},
3717     {25, "No of blocks = 6 and Number of first block = 0"},
3718     {26, "No of blocks = 6 and Number of first block = 1"},
3719     {27, "No of blocks = 7 and Number of first block = 0"},
3720     {28, "Reserved"},
3721     {29, "Reserved"},
3722     {30, "Reserved"},
3723     {31, "Reserved"},
3724     { 0, NULL }
3725 };
3726
3727 static guint16
3728 de_rr_si1_rest_oct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3729 {
3730     proto_tree  *subtree;
3731     proto_item  *item;
3732     guint32     curr_offset;
3733     gint bit_offset;
3734
3735     len = 1;
3736     curr_offset = offset;
3737     bit_offset = curr_offset << 3;
3738
3739     item = proto_tree_add_text(tree, tvb, curr_offset, len, "%s",
3740                                gsm_rr_elem_strings[DE_RR_SI1_REST_OCT].strptr);
3741
3742     subtree = proto_item_add_subtree(item, ett_gsm_rr_elem[DE_RR_SI1_REST_OCT]);