No need for decoding function for a Tag-only IE
[obnox/wireshark/wip.git] / epan / dissectors / packet-gsm_a_gm.c
1 /* packet-gsm_a_gm.c
2  * Routines for GSM A Interface GPRS Mobilty Management and GPRS Session Management
3  *
4  * Copyright 2003, Michael Lum <mlum [AT] telostech.com>
5  * In association with Telos Technology Inc.
6  *
7  * Added the GPRS Mobility Managment Protocol and
8  * the GPRS Session Managment Protocol
9  *   Copyright 2004, Rene Pilz <rene.pilz [AT] ftw.com>
10  *   In association with Telecommunications Research Center
11  *   Vienna (ftw.)Betriebs-GmbH within the Project Metawin.
12  *
13  * Title                3GPP                    Other
14  *
15  *   Reference [7]
16  *   Mobile radio interface Layer 3 specification;
17  *   Core network protocols;
18  *   Stage 3
19  *   (3GPP TS 24.008 version 5.9.0 Release 5)
20  *
21  *   Reference [8]
22  *   Mobile radio interface Layer 3 specification;
23  *   Core network protocols;
24  *   Stage 3
25  *   (3GPP TS 24.008 version 6.7.0 Release 6)
26  *       (3GPP TS 24.008 version 6.8.0 Release 6)
27  *
28  *   Reference [9]
29  *   Mobile radio interface Layer 3 specification;
30  *   Core network protocols;
31  *   Stage 3
32  *   (3GPP TS 24.008 version 8.6.0 Release 8)
33  *
34  * $Id$
35  *
36  * Wireshark - Network traffic analyzer
37  * By Gerald Combs <gerald@wireshark.org>
38  * Copyright 1998 Gerald Combs
39  *
40  * This program is free software; you can redistribute it and/or
41  * modify it under the terms of the GNU General Public License
42  * as published by the Free Software Foundation; either version 2
43  * of the License, or (at your option) any later version.
44  *
45  * This program is distributed in the hope that it will be useful,
46  * but WITHOUT ANY WARRANTY; without even the implied warranty of
47  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48  * GNU General Public License for more details.
49  *
50  * You should have received a copy of the GNU General Public License
51  * along with this program; if not, write to the Free Software
52  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
53  */
54
55 #ifdef HAVE_CONFIG_H
56 # include "config.h"
57 #endif
58
59 #include <string.h>
60
61 #include <epan/packet.h>
62 #include <epan/prefs.h>
63 #include <epan/tap.h>
64 #include <epan/asn1.h>
65
66 #include "packet-bssap.h"
67 #include "packet-sccp.h"
68 #include "packet-ber.h"
69 #include "packet-q931.h"
70 #include "packet-gsm_a_common.h"
71 #include "packet-ipv6.h"
72 #include "packet-e212.h"
73 #include "packet-ppp.h"
74
75 /* PROTOTYPES/FORWARDS */
76
77 const value_string gsm_a_dtap_msg_gmm_strings[] = {
78         { 0x01, "Attach Request" },
79         { 0x02, "Attach Accept" },
80         { 0x03, "Attach Complete" },
81         { 0x04, "Attach Reject" },
82         { 0x05, "Detach Request" },
83         { 0x06, "Detach Accept" },
84         { 0x08, "Routing Area Update Request" },
85         { 0x09, "Routing Area Update Accept" },
86         { 0x0a, "Routing Area Update Complete" },
87         { 0x0b, "Routing Area Update Reject" },
88         { 0x0c, "Service Request" },
89         { 0x0d, "Service Accept" },
90         { 0x0e, "Service Reject" },
91         { 0x10, "P-TMSI Reallocation Command" },
92         { 0x11, "P-TMSI Reallocation Complete" },
93         { 0x12, "Authentication and Ciphering Req" },
94         { 0x13, "Authentication and Ciphering Resp" },
95         { 0x14, "Authentication and Ciphering Rej" },
96         { 0x1c, "Authentication and Ciphering Failure" },
97         { 0x15, "Identity Request" },
98         { 0x16, "Identity Response" },
99         { 0x20, "GMM Status" },
100         { 0x21, "GMM Information" },
101         { 0, NULL }
102 };
103
104 const value_string gsm_a_dtap_msg_sm_strings[] = {
105         { 0x41, "Activate PDP Context Request" },
106         { 0x42, "Activate PDP Context Accept" },
107         { 0x43, "Activate PDP Context Reject" },
108         { 0x44, "Request PDP Context Activation" },
109         { 0x45, "Request PDP Context Activation rej." },
110         { 0x46, "Deactivate PDP Context Request" },
111         { 0x47, "Deactivate PDP Context Accept" },
112         { 0x48, "Modify PDP Context Request(Network to MS direction)" },
113         { 0x49, "Modify PDP Context Accept (MS to network direction)" },
114         { 0x4a, "Modify PDP Context Request(MS to network direction)" },
115         { 0x4b, "Modify PDP Context Accept (Network to MS direction)" },
116         { 0x4c, "Modify PDP Context Reject" },
117         { 0x4d, "Activate Secondary PDP Context Request" },
118         { 0x4e, "Activate Secondary PDP Context Accept" },
119         { 0x4f, "Activate Secondary PDP Context Reject" },
120         { 0x50, "Reserved: was allocated in earlier phases of the protocol" },
121         { 0x51, "Reserved: was allocated in earlier phases of the protocol" },
122         { 0x52, "Reserved: was allocated in earlier phases of the protocol" },
123         { 0x53, "Reserved: was allocated in earlier phases of the protocol" },
124         { 0x54, "Reserved: was allocated in earlier phases of the protocol" },
125         { 0x55, "SM Status" },
126         { 0x56, "Activate MBMS Context Request" },
127         { 0x57, "Activate MBMS Context Accept" },
128         { 0x58, "Activate MBMS Context Reject" },
129         { 0x59, "Request MBMS Context Activation" },
130         { 0x5a, "Request MBMS Context Activation Reject" },
131         { 0, NULL }
132 };
133
134 const value_string gsm_gm_elem_strings[] = {
135         /* GPRS Mobility Management Information Elements 10.5.5 */
136         { 0x00, "Attach Result" },
137         { 0x00, "Attach Type" },
138         { 0x00, "Cipher Algorithm" },
139         { 0x00, "TMSI Status" },
140         { 0x00, "Detach Type" },
141         { 0x00, "DRX Parameter" },
142         { 0x00, "Force to Standby" },
143         { 0x00, "Force to Standby" },
144         { 0x00, "P-TMSI Signature" },
145         { 0x00, "P-TMSI Signature 2" },
146         { 0x00, "Identity Type 2" },
147         { 0x00, "IMEISV Request" },
148         { 0x00, "Receive N-PDU Numbers List" },
149         { 0x00, "MS Network Capability" },
150         { 0x00, "MS Radio Access Capability" },
151         { 0x00, "GMM Cause" },
152         { 0x00, "Routing Area Identification" },
153         { 0x00, "Update Result" },
154         { 0x00, "Update Type" },
155         { 0x00, "A&C Reference Number" },
156         { 0x00, "A&C Reference Number" },
157         { 0x00, "Service Type" },
158         { 0x00, "Cell Notification" },
159         { 0x00, "PS LCS Capability" },
160         { 0x00, "Network Feature Support" },
161         { 0x00, "Inter RAT information container" },
162         /* Session Management Information Elements 10.5.6 */
163         { 0x00, "Access Point Name" },
164         { 0x00, "Network Service Access Point Identifier" },
165         { 0x00, "Protocol Configuration Options" },
166         { 0x00, "Packet Data Protocol Address" },
167         { 0x00, "Quality Of Service" },
168         { 0x00, "SM Cause" },
169         { 0x00, "Linked TI" },
170         { 0x00, "LLC Service Access Point Identifier" },
171         { 0x00, "Tear Down Indicator" },
172         { 0x00, "Packet Flow Identifier" },
173         { 0x00, "Traffic Flow Template" },
174         /* GPRS Common Information Elements 10.5.7 */
175         { 0x00, "PDP Context Status" },
176         { 0x00, "Radio Priority" },
177         { 0x00, "GPRS Timer" },
178         { 0x00, "GPRS Timer 2" },
179         { 0x00, "Radio Priority 2"},
180         { 0x00, "MBMS context status"},
181         { 0x00, "Spare Nibble"},
182         { 0, NULL }
183 };
184
185 #define DTAP_GMM_IEI_MASK       0xff
186 #define DTAP_SM_IEI_MASK        0xff
187
188 /* Initialize the protocol and registered fields */
189 static int proto_a_gm = -1;
190
191 static int hf_gsm_a_dtap_msg_gmm_type = -1;
192 static int hf_gsm_a_dtap_msg_sm_type = -1;
193 int hf_gsm_a_gm_elem_id = -1;
194 static int hf_gsm_a_qos_delay_cls       = -1;
195 static int hf_gsm_a_qos_qos_reliability_cls = -1;
196 static int hf_gsm_a_qos_traffic_cls = -1;
197 static int hf_gsm_a_qos_del_order = -1;
198 static int hf_gsm_a_qos_del_of_err_sdu = -1;
199 static int hf_gsm_a_qos_ber = -1;
200 static int hf_gsm_a_qos_sdu_err_rat = -1;
201 static int hf_gsm_a_qos_traff_hdl_pri = -1;
202
203 static int hf_gsm_a_gmm_split_on_ccch = -1;
204 static int hf_gsm_a_gmm_non_drx_timer = -1;
205 static int hf_gsm_a_gmm_cn_spec_drs_cycle_len_coef = -1;
206
207 static int hf_gsm_a_ptmsi_sig =-1;
208 static int hf_gsm_a_ptmsi_sig2 =-1;
209
210 static int hf_gsm_a_tft_op_code = -1;
211 static int hf_gsm_a_tft_e_bit = -1;
212 static int hf_gsm_a_tft_pkt_flt = -1;
213 static int hf_gsm_a_tft_ip4_address = -1;
214 static int hf_gsm_a_tft_ip4_mask = -1;
215 static int hf_gsm_a_tft_ip6_address = -1;
216 static int hf_gsm_a_tft_ip6_mask = -1;
217 static int hf_gsm_a_tft_protocol_header = -1;
218 static int hf_gsm_a_tft_port = -1;
219 static int hf_gsm_a_tft_port_low = -1;
220 static int hf_gsm_a_tft_port_high = -1;
221 static int hf_gsm_a_tft_security = -1;
222 static int hf_gsm_a_tft_traffic_mask = -1;
223 static int hf_gsm_a_gm_acc_tech_type = -1;
224 static int hf_gsm_a_gm_acc_cap_struct_len = -1;
225 static int hf_gsm_a_gm_sms_value = -1;
226 static int hf_gsm_a_gm_sm_value = -1;
227 static int hf_gsm_a_gm_sm_ext = -1;
228 static int hf_gsm_a_gm_cause = -1;
229
230 static int hf_gsm_a_gm_fop = -1;
231 static int hf_gsm_a_gm_res_of_attach = -1;
232 static int hf_gsm_a_gm_type_of_ciph_alg = -1;
233 static int hf_gsm_a_gm_imeisv_req = -1;
234 static int hf_gsm_a_gm_ac_ref_nr = -1;
235 static int hf_gsm_a_gm_force_to_standby = -1;
236 static int hf_gsm_a_gm_serv_type = -1;
237 static int hf_gsm_a_gm_ciph_key_seq_num = -1;
238 static int hf_gsm_a_gm_for = -1;
239 static int hf_gsm_a_gm_type_of_attach = -1;
240 static int hf_gsm_a_gm_tmsi_flag = -1;
241 static int hf_gsm_a_gm_update_type = -1;
242
243 /* Initialize the subtree pointers */
244 static gint ett_tc_component = -1;
245 static gint ett_tc_invoke_id = -1;
246 static gint ett_tc_linked_id = -1;
247 static gint ett_tc_opr_code = -1;
248 static gint ett_tc_err_code = -1;
249 static gint ett_tc_prob_code = -1;
250 static gint ett_tc_sequence = -1;
251
252 static gint ett_gmm_drx = -1;
253 static gint ett_gmm_detach_type = -1;
254 static gint ett_gmm_attach_type = -1;
255 static gint ett_gmm_context_stat = -1;
256 static gint ett_gmm_update_type = -1;
257 static gint ett_gmm_radio_cap = -1;
258 static gint ett_gmm_rai = -1;
259
260 static gint ett_sm_tft = -1;
261
262 static dissector_handle_t data_handle;
263 static dissector_handle_t rrc_irat_ho_info_handle;
264
265 static dissector_table_t gprs_sm_pco_subdissector_table; /* GPRS SM PCO PPP Protocols */
266
267 #define NUM_GSM_GM_ELEM (sizeof(gsm_gm_elem_strings)/sizeof(value_string))
268 gint ett_gsm_gm_elem[NUM_GSM_GM_ELEM];
269
270 static const gchar *pdp_str[2]={ "PDP-INACTIVE", "PDP-ACTIVE" };
271
272 /*
273  * [9] 10.5.5.1 Attach result
274  */
275 static const value_string gsm_a_gm_res_of_attach_vals[] = {
276         { 0x01, "GPRS only attached" },
277         { 0x03, "Combined GPRS/IMSI attached" },
278         { 0, NULL }
279 };
280
281 static guint16
282 de_gmm_attach_res(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
283 {
284         proto_tree_add_item(tree, hf_gsm_a_gm_fop, tvb, offset, 1, FALSE);
285         proto_tree_add_item(tree, hf_gsm_a_gm_res_of_attach, tvb, offset, 1, FALSE);
286
287         /* no length check possible */
288         return(1);
289 }
290
291 /*
292  * [9] 10.5.5.2 Attach type
293  */
294 static const value_string gsm_a_gm_type_of_attach_vals[] = {
295         { 0x01, "GPRS attach" },
296         { 0x02, "Not used (In earlier versions: GPRS attach while IMSI attached)" },
297         { 0x03, "Combined GPRS/IMSI attached" },
298         { 0, NULL }
299 };
300
301 static guint16
302 de_gmm_attach_type(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
303 {
304         proto_item   *tf = NULL;
305         proto_tree   *tf_tree = NULL;
306
307         proto_tree_add_bits_item(tree, hf_gsm_a_gm_ciph_key_seq_num, tvb, offset << 3, 4, FALSE);
308
309         tf = proto_tree_add_text(tree,
310                 tvb, offset, 1,
311                 "Attach Type");
312
313         tf_tree = proto_item_add_subtree(tf, ett_gmm_attach_type );
314
315         proto_tree_add_item(tf_tree, hf_gsm_a_gm_for, tvb, offset, 1, FALSE);
316         proto_tree_add_item(tf_tree, hf_gsm_a_gm_type_of_attach, tvb, offset, 1, FALSE);
317
318         /* no length check possible */
319         return(1);
320 }
321
322 /*
323  * [9] 10.5.5.3 Ciphering algorithm
324  */
325 static const value_string gsm_a_gm_type_of_ciph_alg_vals[] = {
326         { 0x00, "ciphering not used" },
327         { 0x01, "GPRS Encryption Algorithm GEA/1" },
328         { 0x02, "GPRS Encryption Algorithm GEA/2" },
329         { 0x03, "GPRS Encryption Algorithm GEA/3" },
330         { 0x04, "GPRS Encryption Algorithm GEA/4" },
331         { 0x05, "GPRS Encryption Algorithm GEA/5" },
332         { 0x06, "GPRS Encryption Algorithm GEA/6" },
333         { 0x07, "GPRS Encryption Algorithm GEA/7" },
334         { 0, NULL }
335 };
336
337 static guint16
338 de_gmm_ciph_alg(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
339 {
340         proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (offset << 3) + 4, 1, FALSE);
341         proto_tree_add_item(tree, hf_gsm_a_gm_type_of_ciph_alg, tvb, offset, 1, FALSE);
342
343         /* no length check possible */
344         return(1);
345 }
346
347 /*
348  * [9] 10.5.5.4 TMSI status
349  */
350 const true_false_string gsm_a_gm_tmsi_flag_value = {
351         "valid TMSI available",
352         "no valid TMSI available"
353 };
354
355 static guint16
356 de_gmm_tmsi_stat(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
357 {
358         proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (offset << 3) + 4, 3, FALSE);
359         proto_tree_add_item(tree, hf_gsm_a_gm_tmsi_flag, tvb, offset, 1, FALSE);
360
361         /* no length check possible */
362         return(1);
363 }
364
365 /*
366  * [7] 10.5.5.5
367  */
368 static guint16
369 de_gmm_detach_type(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
370 {
371         guint8        oct;
372         guint32       curr_offset;
373         const gchar  *str;
374         const gchar  *str_power;
375         proto_item   *tf = NULL;
376         proto_tree   *tf_tree = NULL;
377
378         curr_offset = offset;
379
380         oct = tvb_get_guint8(tvb, curr_offset);
381
382         switch(oct&7)
383         {
384                 case 1:  str="GPRS detach/re-attach required";                            break;
385                 case 2:  str="IMSI detach/re-attach not required";                        break;
386                 case 3:  str="Combined GPRS/IMSI detach/IMSI detach (after VLR failure)"; break;
387                 default: str="Combined GPRS/IMSI detach/re-attach not required";
388         }
389
390         switch(oct&8)
391         {
392                 case 8:  str_power="power switched off"; break;
393                 default: str_power="normal detach";      break;
394         }
395
396         tf = proto_tree_add_text(tree,
397                 tvb, curr_offset, 1,
398                 "Detach Type");
399
400         tf_tree = proto_item_add_subtree(tf, ett_gmm_detach_type );
401
402         proto_tree_add_text(tf_tree,
403                 tvb, curr_offset, 1,
404                 "Type: (%u) %s",
405                 oct&7,
406                 str);
407
408         proto_tree_add_text(tf_tree,
409                 tvb, curr_offset, 1,
410                 "Power: (%u) %s",
411                 (oct>>3)&1,
412                 str_power);
413
414         curr_offset++;
415
416         /* no length check possible */
417
418         return(curr_offset - offset);
419 }
420
421 /*
422  * [7] 10.5.5.6
423  *
424  * SPLIT on CCCH, octet 3 (bit 4)
425  * 0 Split pg cycle on CCCH is not supported by the mobile station
426  * 1 Split pg cycle on CCCH is supported by the mobile station
427  */
428 static const true_false_string gsm_a_gmm_split_on_ccch_value  = {
429         "Split pg cycle on CCCH is supported by the mobile station",
430         "Split pg cycle on CCCH is not supported by the mobile station"
431 };
432
433 /* non-DRX timer, octet 3
434  * bit
435  * 3 2 1
436  */
437 static const value_string gsm_a_gmm_non_drx_timer_strings[] = {
438         { 0x00, "no non-DRX mode after transfer state" },
439         { 0x01, "max. 1 sec non-DRX mode after transfer state" },
440         { 0x02, "max. 2 sec non-DRX mode after transfer state" },
441         { 0x03, "max. 4 sec non-DRX mode after transfer state" },
442         { 0x04, "max. 8 sec non-DRX mode after transfer state" },
443         { 0x05, "max. 16 sec non-DRX mode after transfer state" },
444         { 0x06, "max. 32 sec non-DRX mode after transfer state" },
445         { 0x07, "max. 64 sec non-DRX mode after transfer state" },
446         { 0, NULL },
447 };
448 /*
449  * CN Specific DRX cycle length coefficient, octet 3
450  * bit
451  * 8 7 6 5 Iu mode specific
452  * 0 0 0 0 CN Specific DRX cycle length coefficient not specified by the MS, ie. the
453  * system information value 'CN domain specific DRX cycle length' is used.
454  * (Ref 3GPP TS 25.331)
455  * 0 1 1 0 CN Specific DRX cycle length coefficient 6
456  * 0 1 1 1 CN Specific DRX cycle length coefficient 7
457  * 1 0 0 0 CN Specific DRX cycle length coefficient 8
458  * 1 0 0 1 CN Specific DRX cycle length coefficient 9
459  * All other values shall be interpreted as "CN Specific DRX cycle length coefficient not
460  * specified by the MS " by this version of the protocol.
461  * NOTE: In Iu mode this field (octet 3 bits 8 to 5) is used, but was spare in earlier
462  * versions of this protocol.
463  */
464 static const value_string gsm_a_gmm_cn_spec_drs_cycle_len_coef_strings[] = {
465         { 0x00, "CN Specific DRX cycle length coefficient not specified by the MS" },
466         { 0x01, "CN Specific DRX cycle length coefficient not specified by the MS" },
467         { 0x02, "CN Specific DRX cycle length coefficient not specified by the MS" },
468         { 0x03, "CN Specific DRX cycle length coefficient not specified by the MS" },
469         { 0x04, "CN Specific DRX cycle length coefficient not specified by the MS" },
470         { 0x05, "CN Specific DRX cycle length coefficient not specified by the MS" },
471         { 0x06, "CN Specific DRX cycle length coefficient 6" },
472         { 0x07, "CN Specific DRX cycle length coefficient 7" },
473         { 0x08, "CN Specific DRX cycle length coefficient 8" },
474         { 0x09, "CN Specific DRX cycle length coefficient 9" },
475         { 0x0a, "CN Specific DRX cycle length coefficient not specified by the MS" },
476         { 0x0b, "CN Specific DRX cycle length coefficient not specified by the MS" },
477         { 0x0c, "CN Specific DRX cycle length coefficient not specified by the MS" },
478         { 0x0d, "CN Specific DRX cycle length coefficient not specified by the MS" },
479         { 0x0e, "CN Specific DRX cycle length coefficient not specified by the MS" },
480         { 0x0f, "CN Specific DRX cycle length coefficient not specified by the MS" },
481         { 0, NULL },
482 };
483 guint16
484 de_gmm_drx_param(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
485 {
486         guint8        oct;
487         guint32       curr_offset;
488         const gchar  *str;
489         gchar         str_val[3];
490         proto_item   *tf = NULL;
491         proto_tree   *tf_tree = NULL;
492
493         curr_offset = offset;
494
495         tf = proto_tree_add_text(tree,
496                 tvb, curr_offset, 2,
497                 "DRX Parameter");
498
499         tf_tree = proto_item_add_subtree(tf, ett_gmm_drx );
500
501         oct = tvb_get_guint8(tvb, curr_offset);
502
503         switch(oct)
504         {
505                 case 0:  str="704"; break;
506                 case 65: str="71";  break;
507                 case 66: str="72";  break;
508                 case 67: str="74";  break;
509                 case 68: str="75";  break;
510                 case 69: str="77";  break;
511                 case 70: str="79";  break;
512                 case 71: str="80";  break;
513                 case 72: str="83";  break;
514                 case 73: str="86";  break;
515                 case 74: str="88";  break;
516                 case 75: str="90";  break;
517                 case 76: str="92";  break;
518                 case 77: str="96";  break;
519                 case 78: str="101"; break;
520                 case 79: str="103"; break;
521                 case 80: str="107"; break;
522                 case 81: str="112"; break;
523                 case 82: str="116"; break;
524                 case 83: str="118"; break;
525                 case 84: str="128"; break;
526                 case 85: str="141"; break;
527                 case 86: str="144"; break;
528                 case 87: str="150"; break;
529                 case 88: str="160"; break;
530                 case 89: str="171"; break;
531                 case 90: str="176"; break;
532                 case 91: str="192"; break;
533                 case 92: str="214"; break;
534                 case 93: str="224"; break;
535                 case 94: str="235"; break;
536                 case 95: str="256"; break;
537                 case 96: str="288"; break;
538                 case 97: str="320"; break;
539                 case 98: str="352"; break;
540                 default:
541                          str_val[0]=oct/10+'0';
542                          str_val[1]=oct%10+'0';
543                          str_val[2]=0;
544                          str=str_val;
545         }
546
547         proto_tree_add_text(tf_tree,
548                 tvb, curr_offset, 1,
549                 "Split PG Cycle Code: (%u) %s",
550                 oct,
551                 str);
552
553         curr_offset++;
554         proto_tree_add_item(tf_tree, hf_gsm_a_gmm_cn_spec_drs_cycle_len_coef, tvb, curr_offset, 1, FALSE);
555         proto_tree_add_item(tf_tree, hf_gsm_a_gmm_split_on_ccch, tvb, curr_offset, 1, FALSE);
556         proto_tree_add_item(tf_tree, hf_gsm_a_gmm_non_drx_timer, tvb, curr_offset, 1, FALSE);
557
558         curr_offset++;
559
560         /* no length check possible */
561
562         return(curr_offset - offset);
563 }
564
565 /*
566  * [9] 10.5.5.7 Force to standby (lower nibble)
567  */
568 static const range_string gsm_a_gm_force_to_standby_vals[] = {
569         { 0x00, 0x00, "Force to standby not indicated" },
570         { 0x01, 0x01, "Force to standby indicated" },
571         { 0x02, 0x07, "Unknown, interpreted as Force to standby not indicated" },
572         { 0, 0, NULL }
573 };
574
575 static guint16
576 de_gmm_ftostby(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
577 {
578         guint32 bit_offset;
579
580         /* IMPORTANT - IT'S ASSUMED THAT THE INFORMATION IS IN THE LOWER NIBBLE */
581         bit_offset = (offset << 3) + 4;
582         proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, bit_offset, 1, FALSE);
583         proto_tree_add_bits_item(tree, hf_gsm_a_gm_force_to_standby, tvb, bit_offset + 1, 3, FALSE);
584
585         /* no length check possible */
586         return(1);
587 }
588
589 /*
590  * [9] 10.5.5.7 Force to standby (higher nibble)
591  */
592 static guint16
593 de_gmm_ftostby_h(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
594 {
595         guint32 bit_offset;
596
597         /* IMPORTANT - IT'S ASSUMED THAT THE INFORMATION IS IN THE HIGHER NIBBLE */
598         bit_offset = offset << 3;
599         proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, bit_offset, 1, FALSE);
600         proto_tree_add_bits_item(tree, hf_gsm_a_gm_force_to_standby, tvb, bit_offset + 1, 3, FALSE);
601
602         /* no length check possible */
603         return(1);
604 }
605
606 /*
607  * [7] 10.5.5.8
608  */
609 static guint16
610 de_gmm_ptmsi_sig(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
611 {
612         guint32       curr_offset;
613         proto_item   *curr_item;
614
615         curr_offset = offset;
616         
617         curr_item= proto_tree_add_item(tree,hf_gsm_a_ptmsi_sig,tvb,curr_offset,3,FALSE);
618         proto_item_append_text(curr_item,"%s",add_string ? add_string : "");
619
620         curr_offset+=3;
621
622         /* no length check possible */
623
624         return(curr_offset - offset);
625 }
626
627 /*
628  * [7] 10.5.5.8a
629  */
630 static guint16
631 de_gmm_ptmsi_sig2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len _U_)
632 {
633         guint32       curr_offset;
634         proto_item   *curr_item;
635
636         curr_offset = offset;
637
638         curr_item= proto_tree_add_item(tree,hf_gsm_a_ptmsi_sig2,tvb,curr_offset,3,FALSE);
639         proto_item_append_text(curr_item,"%s",add_string ? add_string : "");
640         curr_offset+=3;
641
642         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
643
644         return(curr_offset - offset);
645 }
646
647 /*
648  * [7] 10.5.5.9
649  */
650 static guint16
651 de_gmm_ident_type2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
652 {
653         guint8        oct;
654         guint32       curr_offset;
655         const gchar  *str;
656
657         curr_offset = offset;
658
659         oct = tvb_get_guint8(tvb, curr_offset);
660
661         switch ( oct&7 )
662         {
663                 case 2:  str="IMEI";   break;
664                 case 3:  str="IMEISV"; break;
665                 case 4:  str="TMSI";   break;
666                 default: str="IMSI";
667         }
668
669         proto_tree_add_text(tree,
670                 tvb, curr_offset, 1,
671                 "Identity Type 2: (%u) %s",
672                 oct&7,
673                 str);
674
675         curr_offset++;
676
677         /* no length check possible */
678
679         return(curr_offset - offset);
680 }
681
682 /*
683  * [9] 10.5.5.10 IMEISV request
684  */
685 static const range_string gsm_a_gm_imeisv_req_vals[] = {
686         { 0x00, 0x00, "IMEISV not requested" },
687         { 0x01, 0x01, "IMEISV requested" },
688         { 0x02, 0x07, "Unknown, interpreted as IMEISV not requested" },
689         { 0, 0, NULL }
690 };
691
692 static guint16
693 de_gmm_imeisv_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
694 {
695         guint32 bit_offset;
696
697         /* IMPORTANT - IT'S ASSUMED THAT THE INFORMATION IS IN THE HIGHER NIBBLE */
698         bit_offset = offset << 3;
699         proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, bit_offset, 1, FALSE);
700         proto_tree_add_bits_item(tree, hf_gsm_a_gm_imeisv_req, tvb, bit_offset + 1, 3, FALSE);
701
702         /* no length check possible */
703         return(1);
704 }
705
706 /*
707  * [7] 10.5.5.11
708  */
709 static guint16
710 de_gmm_rec_npdu_lst(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
711 {
712         guint32 curr_offset;
713         guint   curr_len;
714
715         curr_len = len;
716         curr_offset = offset;
717
718         if ( len == 0 ) return 0;
719
720         do
721         {
722                 guint32 oct;
723                 oct = tvb_get_guint8(tvb, curr_offset);
724                 oct <<=8;
725                 oct |= tvb_get_guint8(tvb, curr_offset+1);
726                 curr_len -= 2;
727                 oct <<=8;
728
729                 proto_tree_add_text(tree,
730                         tvb, curr_offset, 2,
731                         "NSAPI %d: 0x%02x (%u)",
732                         oct>>20,
733                         (oct>>12)&0xff,
734                         (oct>>12)&0xff);
735                 curr_offset+= 2;
736
737                 if ( curr_len > 2 )
738                 {
739                         oct |= tvb_get_guint8(tvb, curr_offset+2);
740                         curr_len--;
741                         oct <<= 12;
742
743                         proto_tree_add_text(tree,
744                                 tvb, curr_offset-1, 2,
745                                 "NSAPI %d: 0x%02x (%u)",
746                                 oct>>20,
747                                 (oct>>12)&0xff,
748                                 (oct>>12)&0xff);
749                         curr_offset++;
750                 }
751
752         } while ( curr_len > 1 );
753
754         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
755
756         return(curr_offset - offset);
757 }
758
759 /*
760  * [7] 10.5.5.12
761  */
762 guint16
763 de_gmm_ms_net_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
764 {
765         guint8  oct;
766         guint32 curr_offset;
767         guint   curr_len;
768         guint   gea_val;
769
770         static const gchar *answer_gea[2]={
771                 "encryption algorithm not available",
772                 "encryption algorithm available" };
773
774         static const gchar *answer_smdch[2]={
775                 "Mobile station does not support mobile terminated point to point SMS via dedicated signalling channels",
776                 "Mobile station supports mobile terminated point to point SMS via dedicated signalling channels" };
777
778         static const gchar *answer_smgprs[2]={
779                 "Mobile station does not support mobile terminated point to point SMS via GPRS packet data channels",
780                 "Mobile station supports mobile terminated point to point SMS via GPRS packet data channels" };
781
782         static const gchar *answer_ucs2[2]= {
783                 "the ME has a preference for the default alphabet (defined in 3GPP TS 23.038 [8b]) over UCS2",
784                 "the ME has no preference between the use of the default alphabet and the use of UCS2" };
785
786         static const gchar *answer_ssid[4]={
787                 "default value of phase 1",
788                 "capability of handling of ellipsis notation and phase 2 error handling",
789                 "capability of handling of ellipsis notation and phase 2 error handling",
790                 "capability of handling of ellipsis notation and phase 2 error handling" };
791
792         static const gchar *answer_solsa[2]={
793                 "The ME does not support SoLSA",
794                 "The ME supports SoLSA" };
795                         
796         static const gchar *answer_rev[2]={
797                 "used by a mobile station not supporting R99 or later versions of the protocol",
798                 "used by a mobile station supporting R99 or later versions of the protocol" };
799
800         static const gchar *answer_pfc[2]={
801                 "Mobile station does not support BSS packet flow procedures",
802                 "Mobile station does support BSS packet flow procedures" };
803
804         static const gchar *answer_lcs[2]={
805                 "LCS value added location request notification capability not supported" ,
806                 "LCS value added location request notification capability supported" };
807
808         static const gchar *answer_ps_irat[2]={
809                 "PS inter-RAT HO to UTRAN Iu mode not supported" ,
810                 "PS inter-RAT HO to UTRAN Iu mode supported" };
811
812         curr_len = len;
813         curr_offset = offset;
814
815         if ( curr_len == 0 ){ EXTRANEOUS_DATA_CHECK(len, curr_offset - offset); return(curr_offset - offset); }
816         oct = tvb_get_guint8(tvb, curr_offset);
817         curr_len--;
818
819         /* bit 8 */
820         proto_tree_add_text(tree,
821                 tvb, curr_offset, 1,
822                 "GEA1: (%u) %s",
823                 oct>>7,
824                 answer_gea[oct>>7]);
825         oct<<=1;
826
827         /* bit 7 */
828         proto_tree_add_text(tree,
829                 tvb, curr_offset, 1,
830                 "SM capabilities via dedicated channels: (%u) %s",
831                 oct>>7,
832                 answer_smdch[oct>>7]);
833         oct<<=1;
834
835         /* bit 6 */
836         proto_tree_add_text(tree,
837                 tvb, curr_offset, 1,
838                 "SM capabilities via GPRS channels: (%u) %s",
839                 oct>>7,
840                 answer_smgprs[oct>>7]);
841         oct<<=1;
842
843         /* bit 5 */
844         proto_tree_add_text(tree,
845                 tvb, curr_offset, 1,
846                 "UCS2 support: (%u) %s",
847                 oct>>7,
848                 answer_ucs2[oct>>7]);
849         oct<<=1;
850
851         /* bit 4 3 */
852         proto_tree_add_text(tree,
853                 tvb, curr_offset, 1,
854                 "SS Screening Indicator: (%u) %s",
855                 oct>>6,
856                 answer_ssid[oct>>6]);
857         oct<<=2;
858
859         /* bit 2 */
860         proto_tree_add_text(tree,
861                 tvb, curr_offset, 1,
862                 "SoLSA Capability: (%u) %s",
863                 oct>>7,
864                 answer_solsa[oct>>7]);
865         oct<<=1;
866
867         /* bit 1 */
868         proto_tree_add_text(tree,
869                 tvb, curr_offset, 1,
870                 "Revision level indicator: (%u) %s",
871                 oct>>7,
872                 answer_rev[oct>>7]);
873
874         curr_offset++;
875
876         if ( curr_len == 0 ){ EXTRANEOUS_DATA_CHECK(len, curr_offset - offset); return(curr_offset - offset); }
877         oct = tvb_get_guint8(tvb, curr_offset);
878         curr_len--;
879
880         proto_tree_add_text(tree,
881                 tvb, curr_offset, 1,
882                 "PFC feature mode: (%u) %s",
883                 oct>>7,
884                 answer_pfc[oct>>7]);
885         oct<<=1;
886
887         for( gea_val=2; gea_val<8 ; gea_val++ )
888         {
889                 proto_tree_add_text(tree,
890                         tvb, curr_offset, 1,
891                         "GEA%d: (%u) %s", gea_val,
892                         oct>>7,
893                         answer_gea[oct>>7]);
894                 oct<<=1;
895         }
896
897         proto_tree_add_text(tree,
898                 tvb, curr_offset, 1,
899                 "LCS VA capability: (%u) %s",
900                 oct>>7,
901                 answer_lcs[oct>>7]);
902
903         curr_offset++;
904
905     if ( curr_len == 0 ){ EXTRANEOUS_DATA_CHECK(len, curr_offset - offset); return(curr_offset - offset); }
906     oct = tvb_get_guint8(tvb, curr_offset);
907     curr_len--;
908
909     proto_tree_add_text(tree,
910                         tvb, curr_offset, 1,
911                         "PS inter-RAT HO to UTRAN Iu mode capability: (%u) %s",
912                         oct & 0x1,                    /* XXX: There's only 2 entries in the ..._irat array  */
913                         answer_ps_irat[oct & 0x1]);   /*      so we'll assume that this is a 1 bit value.   */
914
915
916     proto_tree_add_text(tree,
917                         tvb, curr_offset, 1,
918                         "Spare: (%u)",
919                         oct>>1);
920
921     curr_offset++;
922     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
923
924         return(curr_offset - offset);
925 }
926
927 /*
928  * [7] 10.5.5.12a
929  */
930 #define GET_DATA                                /* check if we have enough bits left */ \
931         if ( curr_bits_length < bits_needed ) \
932                 continue; \
933         /* check if oct has enougth bits */ \
934         if ( bits_in_oct < bits_needed ) \
935         { \
936                 guint32 tmp_oct; \
937                 if ( curr_len == 0 ) \
938                 { \
939                         proto_tree_add_text(tf_tree, \
940                                 tvb, curr_offset, 1, \
941                                 "Not enough data available"); \
942                 } \
943                 tmp_oct = tvb_get_guint8(tvb, curr_offset); \
944                 oct |= tmp_oct<<(32-8-bits_in_oct); \
945                 curr_len--; \
946                 curr_offset++; \
947                 if ( bits_in_oct != 0 ) \
948                         add_ocetets = 1; \
949                 else \
950                         add_ocetets = 0; \
951                 bits_in_oct += 8; \
952         } \
953         else \
954                 add_ocetets = 0;
955
956 /* Access Technology Type */
957
958 static const value_string gsm_a_gm_acc_tech_type_vals[] = {
959         { 0x00, "GSM P" },
960         { 0x01, "GSM E --note that GSM E covers GSM P" },
961         { 0x02, "GSM R --note that GSM R covers GSM E and GSM P" },
962         { 0x03, "GSM 1800" },
963         { 0x04, "GSM 1900" },
964         { 0x05, "GSM 450" },
965         { 0x06, "GSM 480" },
966         { 0x07, "GSM 850" },
967         { 0x08, "GSM 750" },
968         { 0x09, "GSM T 380" },
969         { 0x0a, "GSM T 410" },
970         { 0x0b, "GSM T 900" },
971         { 0x0c, "GSM 710" },
972         { 0x0d, "GSM T 810" },
973         { 0x0f, "Indicates the presence of a list of Additional access technologies" },
974         { 0, NULL }
975 };
976
977 /* SMS_VALUE (Switch-Measure-Switch) (4 bit field) */
978
979 static const value_string gsm_a_gm_sm_vals[] = {
980         { 0x00, "1/4 timeslot (~144 microseconds)" },
981         { 0x01, "2/4 timeslot (~288 microseconds)" },
982         { 0x02, "3/4 timeslot (~433 microseconds)" },
983         { 0x03, "4/4 timeslot (~577 microseconds)" },
984         { 0x04, "5/4 timeslot (~721 microseconds)" },
985         { 0x05, "6/4 timeslot (~865 microseconds)" },
986         { 0x06, "7/4 timeslot (~1009 microseconds)" },
987         { 0x07, "8/4 timeslot (~1154 microseconds)" },
988         { 0x08, "9/4 timeslot (~1297 microseconds)" },
989         { 0x09, "10/4 timeslot (~1441 microseconds)" },
990         { 0x0a, "11/4 timeslot (~1586 microseconds)" },
991         { 0x0b, "12/4 timeslot (~1730 microseconds)" },
992         { 0x0c, "13/4 timeslot (~1874 microseconds)" },
993         { 0x0d, "14/4 timeslot (~2018 microseconds)" },
994         { 0x0e, "15/4 timeslot (~2163 microseconds)" },
995         { 0x0f, "16/4 timeslot (~2307 microseconds)" },
996         { 0, NULL }
997 };
998 guint16
999 de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
1000 {
1001         guint32      curr_offset;
1002         guint        curr_len;
1003         int          bit_offset;
1004         proto_item  *tf = NULL;
1005         proto_tree  *tf_tree = NULL;
1006         guint32      oct;
1007         guchar       bits_in_oct;
1008         guchar       bits_needed;
1009         guint        bits_length;
1010         guint        add_ocetets;       /* octets which are covered by one element -1 */
1011         guint        curr_bits_length;
1012         guchar       acc_type;
1013         guint        value;
1014         const gchar *str;
1015         /** XXX: AFAIT only the first 32 entries of the following are actually used. Is this a bug someplace ?? */
1016         static const gchar *multi_slot_str[64] = {
1017                 "Not specified", /* 00 */
1018                 "Max Rx-Slot/TDMA:1 Max Tx-Slot/TDMA:1 Max-Sum-Slot/TDMA:2 Tta:3 Ttb:2 Tra:4 Trb:2 Type:1", /* 01 */
1019                 "Max Rx-Slot/TDMA:2 Max Tx-Slot/TDMA:1 Max-Sum-Slot/TDMA:3 Tta:3 Ttb:2 Tra:3 Trb:1 Type:1", /* 02 */
1020                 "Max Rx-Slot/TDMA:2 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:3 Tta:3 Ttb:2 Tra:3 Trb:1 Type:1", /* 03 */
1021                 "Max Rx-Slot/TDMA:3 Max Tx-Slot/TDMA:1 Max-Sum-Slot/TDMA:4 Tta:3 Ttb:1 Tra:3 Trb:1 Type:1", /* 04 */
1022                 "Max Rx-Slot/TDMA:2 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:4 Tta:3 Ttb:1 Tra:3 Trb:1 Type:1", /* 05 */
1023                 "Max Rx-Slot/TDMA:3 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:4 Tta:3 Ttb:1 Tra:3 Trb:1 Type:1", /* 06 */
1024                 "Max Rx-Slot/TDMA:3 Max Tx-Slot/TDMA:3 Max-Sum-Slot/TDMA:4 Tta:3 Ttb:1 Tra:3 Trb:1 Type:1", /* 07 */
1025                 "Max Rx-Slot/TDMA:4 Max Tx-Slot/TDMA:1 Max-Sum-Slot/TDMA:5 Tta:3 Ttb:1 Tra:2 Trb:1 Type:1", /* 08 */
1026                 "Max Rx-Slot/TDMA:3 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:5 Tta:3 Ttb:1 Tra:2 Trb:1 Type:1", /* 09 */
1027                 "Max Rx-Slot/TDMA:4 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:5 Tta:3 Ttb:1 Tra:2 Trb:1 Type:1", /* 10 */
1028                 "Max Rx-Slot/TDMA:4 Max Tx-Slot/TDMA:3 Max-Sum-Slot/TDMA:5 Tta:3 Ttb:1 Tra:2 Trb:1 Type:1", /* 11 */
1029                 "Max Rx-Slot/TDMA:4 Max Tx-Slot/TDMA:4 Max-Sum-Slot/TDMA:5 Tta:2 Ttb:1 Tra:2 Trb:1 Type:1", /* 12 */
1030                 "Max Rx-Slot/TDMA:3 Max Tx-Slot/TDMA:3 Max-Sum-Slot/TDMA:NA Tta:NA Ttb:a) Tra:3 Trb:a) Type:2 (a: 1 with frequency hopping, 0 otherwise)", /* 13 */
1031                 "Max Rx-Slot/TDMA:4 Max Tx-Slot/TDMA:4 Max-Sum-Slot/TDMA:NA Tta:NA Ttb:a) Tra:3 Trb:a) Type:2 (a: 1 with frequency hopping, 0 otherwise)", /* 14 */
1032                 "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:5 Max-Sum-Slot/TDMA:NA Tta:NA Ttb:a) Tra:3 Trb:a) Type:2 (a: 1 with frequency hopping, 0 otherwise)", /* 15 */
1033                 "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:6 Max-Sum-Slot/TDMA:NA Tta:NA Ttb:a) Tra:2 Trb:a) Type:2 (a: 1 with frequency hopping, 0 otherwise)", /* 16 */
1034                 "Max Rx-Slot/TDMA:7 Max Tx-Slot/TDMA:7 Max-Sum-Slot/TDMA:NA Tta:NA Ttb:a) Tra:1 Trb:0 Type:2 (a: 1 with frequency hopping, 0 otherwise)", /* 17 */
1035                 "Max Rx-Slot/TDMA:8 Max Tx-Slot/TDMA:8 Max-Sum-Slot/TDMA:NA Tta:NA Ttb:0 Tra:0 Trb:0 Type:2", /* 18 */
1036                 "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 19 */   
1037                 "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:3 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 20 */
1038                 "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:4 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 21 */
1039                 "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:4 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 22 */
1040                 "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:6 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 23 */
1041                 "Max Rx-Slot/TDMA:8 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 24 */
1042                 "Max Rx-Slot/TDMA:8 Max Tx-Slot/TDMA:3 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 25 */
1043                 "Max Rx-Slot/TDMA:8 Max Tx-Slot/TDMA:4 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 26 */
1044                 "Max Rx-Slot/TDMA:8 Max Tx-Slot/TDMA:4 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 27 */
1045                 "Max Rx-Slot/TDMA:8 Max Tx-Slot/TDMA:6 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 28 */
1046                 "Max Rx-Slot/TDMA:8 Max Tx-Slot/TDMA:8 Max-Sum-Slot/TDMA:NA Tta:3 Ttb:b) Tra:2 Trb:c) Type:1 (b: 1 with frequency hopping or change from Rx to Tx, 0 otherwise; c: 1 with frequency hopping or change from Tx to Rx, 0 otherwise", /* 29 */
1047                 "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:1 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1 Trb:1 Type:1", /* 30 */
1048                 "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1 Trb:1 Type:1", /* 31 */
1049                 "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:3 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1 Trb:1 Type:1", /* 32 */
1050                 "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:4 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1 Trb:1 Type:1", /* 33 */
1051                 "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:5 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1 Trb:1 Type:1", /* 34 */
1052                 "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:1 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1+to Trb:1 Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 35 */
1053                 "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1+to Trb:1 Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 36 */
1054                 "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:3 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1+to Trb:1 Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 37 */
1055                 "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:4 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1+to Trb:1 Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 38 */
1056                 "Max Rx-Slot/TDMA:5 Max Tx-Slot/TDMA:5 Max-Sum-Slot/TDMA:6 Tta:2 Ttb:1 Tra:1+to Trb:1 Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 39 */
1057                 "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:1 Max-Sum-Slot/TDMA:7 Tta:1 Ttb:1 Tra:1 Trb:to Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 40 */
1058                 "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:2 Max-Sum-Slot/TDMA:7 Tta:1 Ttb:1 Tra:1 Trb:to Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 41 */
1059                 "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:3 Max-Sum-Slot/TDMA:7 Tta:1 Ttb:1 Tra:1 Trb:to Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 42 */
1060                 "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:4 Max-Sum-Slot/TDMA:7 Tta:1 Ttb:1 Tra:1 Trb:to Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 43 */
1061                 "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:5 Max-Sum-Slot/TDMA:7 Tta:1 Ttb:1 Tra:1 Trb:to Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 44 */
1062                 "Max Rx-Slot/TDMA:6 Max Tx-Slot/TDMA:6 Max-Sum-Slot/TDMA:7 Tta:1 Ttb:1 Tra:1 Trb:to Type:1 (to: to = 31 symbol periods (this can be provided by a TA offset, i.e. a minimum TA value))", /* 45 */
1063                 "Not specified", /* 46 */
1064                 "Not specified", /* 47 */
1065                 "Not specified", /* 48 */
1066                 "Not specified", /* 49 */
1067                 "Not specified", /* 50 */
1068                 "Not specified", /* 51 */
1069                 "Not specified", /* 52 */
1070                 "Not specified", /* 53 */
1071                 "Not specified", /* 54 */
1072                 "Not specified", /* 55 */
1073                 "Not specified", /* 56 */
1074                 "Not specified", /* 57 */
1075                 "Not specified", /* 58 */
1076                 "Not specified", /* 59 */
1077                 "Not specified", /* 60 */
1078                 "Not specified", /* 61 */
1079                 "Not specified", /* 62 */
1080                 "Not specified", /* 63 */
1081         };
1082         guint indx = 0;
1083         guchar dtm_gprs_mslot = 0;
1084         guchar dtm_egprs_mslot = 4;
1085         gboolean finished = TRUE;
1086
1087         curr_len = len;
1088         curr_offset = offset;
1089         bit_offset = offset<<3;
1090
1091         bits_in_oct = 0;
1092         oct = 0;
1093
1094
1095         do
1096         {
1097                 /* check for a new round */
1098                 if (( curr_len*8 + bits_in_oct ) < 11 )
1099                         break;
1100
1101                 /* now read the first 11 bits */
1102                 curr_bits_length = 11;
1103                 /*
1104                  *
1105                  */
1106                 if ( curr_len != len )
1107                 {
1108                         bits_needed = 1;
1109                         GET_DATA;
1110
1111                         if (( oct>>(32-bits_needed) ) == 1 )
1112                         {
1113                                 curr_bits_length -= bits_needed;
1114                                 oct <<= bits_needed;
1115                                 bits_in_oct -= bits_needed;
1116                         
1117                                 if (( curr_len*8 + bits_in_oct ) < 11 )
1118                                         break;
1119                                 curr_bits_length = 11;
1120                         }
1121                         else
1122                         {
1123                                 curr_bits_length -= bits_needed;
1124                                 oct <<= bits_needed;
1125                                 bits_in_oct -= bits_needed;
1126                                 break;
1127                         }
1128                 }
1129
1130                 indx++;
1131                 tf = proto_tree_add_text(tree,
1132                                 tvb, curr_offset, 1,
1133                                 "MS RA capability %d",indx);
1134
1135                 tf_tree = proto_item_add_subtree(tf, ett_gmm_radio_cap );
1136
1137                 /*
1138                  * Access Technology
1139                  */
1140                 bits_needed = 4;
1141                 GET_DATA;
1142
1143                 acc_type = oct>>(32-bits_needed);
1144
1145                 proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_acc_tech_type, tvb, bit_offset, 4, FALSE);
1146                 bit_offset+=4;
1147
1148                 curr_bits_length -= bits_needed;
1149                 oct <<= bits_needed;
1150                 bits_in_oct -= bits_needed;
1151
1152                 /* < Access capabilities struct > ::= */
1153                 /*
1154                  * get bits_length
1155                  */
1156                 bits_needed = 7;
1157                 GET_DATA;
1158
1159                 bits_length = curr_bits_length = oct>>(32-bits_needed);
1160                 proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_acc_cap_struct_len, tvb, bit_offset, 7, FALSE);
1161                 proto_item_set_len(tf, (bits_length>>3)+1);
1162                 /* This is already done - length doesn't contain this field
1163                  curr_bits_length -= bits_needed;
1164                 */
1165                 bit_offset+=7;
1166                 oct <<= bits_needed;
1167                 bits_in_oct -= bits_needed;
1168
1169                 if ( acc_type == 0x0f )
1170                 {
1171                         do
1172                         {
1173                                 /*
1174                                  * Additional access technologies:
1175                                  */
1176                                 finished = TRUE; /* Break out of the loop unless proven unfinished */
1177
1178                                 /*
1179                                  * Presence bit
1180                                  */
1181                                 bits_needed = 1;
1182                                 GET_DATA;
1183
1184                                 /* analyse bits */
1185                                 switch ( oct>>(32-bits_needed) )
1186                                 {
1187                                         case 0x00: str="Not Present"; finished = TRUE; break;
1188                                         case 0x01: str="Present"; finished = FALSE;    break;
1189                                         default:   str="This should not happen";
1190                                 }
1191
1192                                 proto_tree_add_text(tf_tree,
1193                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1194                                         "Presence: (%u) %s",oct>>(32-bits_needed),str);
1195                                 bit_offset++;
1196                                 curr_bits_length -= bits_needed;
1197                                 oct <<= bits_needed;
1198                                 bits_in_oct -= bits_needed;
1199
1200                                 if (finished)
1201                                 {
1202                                         /*
1203                                          * No more valid data, get spare bits if any
1204                                          */
1205                                         while ( curr_bits_length > 0 )
1206                                         {
1207                                                 if ( curr_bits_length > 8 )
1208                                                         bits_needed = 8;
1209                                                 else
1210                                                         bits_needed = curr_bits_length;
1211                                                 GET_DATA;
1212                                                 curr_bits_length -= bits_needed;
1213                                                 oct <<= bits_needed;
1214                                                 bits_in_oct -= bits_needed;
1215                                                 bit_offset+= bits_needed;
1216                                         }
1217                                         continue;
1218                                 }
1219
1220                                 /*
1221                                  * Access Technology
1222                                  */
1223                                 bits_needed = 4;
1224                                 GET_DATA;
1225
1226                                 acc_type = oct>>(32-bits_needed);
1227
1228                                 proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_acc_cap_struct_len, tvb, bit_offset, 7, FALSE);
1229                                 bit_offset+=4;
1230
1231                                 curr_bits_length -= bits_needed;
1232                                 oct <<= bits_needed;
1233                                 bits_in_oct -= bits_needed;
1234
1235                                 /*
1236                                  * RF Power
1237                                  */
1238                                 bits_needed = 3;
1239                                 GET_DATA;
1240
1241                                 value = tvb_get_bits8(tvb, bit_offset, 3);
1242                                 /* analyse bits */
1243                                 if ( acc_type == 0x04 ) /* GSM 1900 */
1244                                 {
1245                                         switch ( value )
1246                                         {
1247                                                 case 0x01: str="1 W (30 dBm)";    break;
1248                                                 case 0x02: str="0,25 W (24 dBm)"; break;
1249                                                 case 0x03: str="2 W (33 dBm)";    break;
1250                                                 default:   str="Not specified";
1251                                         }
1252                                 }
1253                                 else if ( acc_type == 0x03 )
1254                                 {
1255                                         /*
1256                                          * 3 GSM 1800
1257                                          */
1258                                         switch ( value )
1259                                         {
1260                                                 case 0x01: str="1 W (30 dBm)";    break;
1261                                                 case 0x02: str="0,25 W (24 dBm)"; break;
1262                                                 case 0x03: str="4 W (36 dBm)";    break;
1263                                                 default:   str="Not specified";
1264                                         }
1265                                 }
1266                                 else if ( acc_type <= 0x08 )
1267                                 {
1268                                         /* 0 GSM P
1269                                          * 1 GSM E
1270                                          * 2 GSM R 
1271                                          * 5 GSM 450
1272                                          * 6 GSM 480
1273                                          * 7 GSM 850
1274                                          */
1275
1276                                         switch ( value )
1277                                         {
1278                                                 case 0x02: str="8 W (39 dBm)";   break;
1279                                                 case 0x03: str="5 W (37 dBm)";   break;
1280                                                 case 0x04: str="2 W (33 dBm)";   break;
1281                                                 case 0x05: str="0,8 W (29 dBm)"; break;
1282                                                 default:   str="Not specified";
1283                                         }
1284                                 }
1285                                 else
1286                                         str="Not specified??";
1287
1288                                 /* decode_bits_in_field(gint bit_offset, gint no_of_bits, guint64 value)*/
1289                                 proto_tree_add_text(tf_tree,
1290                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1291                                         "%s RF Power Capability, GMSK Power Class: (%u) %s", decode_bits_in_field(bit_offset, 3, value), value, str);
1292                                 bit_offset+=3;
1293                                 curr_bits_length -= bits_needed;
1294                                 oct <<= bits_needed;
1295                                 bits_in_oct -= bits_needed;
1296
1297                                 /*
1298                                  * 8PSK Power Class
1299                                  */
1300                                 bits_needed = 2;
1301                                 GET_DATA;
1302
1303                                 value = tvb_get_bits8(tvb, bit_offset, 2);
1304                                 /* analyse bits */
1305                                 switch ( value )
1306                                 {
1307                                         case 0x00: str="8PSK modulation not supported for uplink"; break;
1308                                         case 0x01: str="Power class E1"; break;
1309                                         case 0x02: str="Power class E2"; break;
1310                                         case 0x03: str="Power class E3"; break;
1311                                         default:   str="This should not happen";
1312                                 }
1313
1314                                 proto_tree_add_text(tf_tree,
1315                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1316                                         "8PSK Power Class: (%u) %s",value,str);
1317                                 bit_offset+=2;
1318                                 curr_bits_length -= bits_needed;
1319                                 oct <<= bits_needed;
1320                                 bits_in_oct -= bits_needed;
1321
1322                         } while (!finished);
1323
1324                         /* goto next one */
1325                         continue;
1326                 }
1327                 /*
1328                  * RF Power
1329                  */
1330                 bits_needed = 3;
1331                 GET_DATA;
1332
1333                 value = tvb_get_bits8(tvb, bit_offset, 3);
1334                 /* analyse bits */
1335                 if ( acc_type == 0x04 ) /* GSM 1900 */
1336                 {
1337                         switch ( value )
1338                         {
1339                                 case 0x01: str="1 W (30 dBm)";    break;
1340                                 case 0x02: str="0,25 W (24 dBm)"; break;
1341                                 case 0x03: str="2 W (33 dBm)";    break;
1342                                 default:   str="Not specified";
1343                         }
1344                 }
1345                 else if ( acc_type == 0x03 )
1346                 {
1347                         switch ( value )
1348                         {
1349                                 case 0x01: str="1 W (30 dBm)";    break;
1350                                 case 0x02: str="0,25 W (24 dBm)"; break;
1351                                 case 0x03: str="4 W (36 dBm)";    break;
1352                                 default:   str="Not specified";
1353                         }
1354                 }
1355                 else if ( acc_type <= 0x08 )
1356                 {
1357                         switch ( value )
1358                         {
1359                                 case 0x02: str="8 W (39 dBm)";   break;
1360                                 case 0x03: str="5 W (37 dBm)";   break;
1361                                 case 0x04: str="2 W (33 dBm)";   break;
1362                                 case 0x05: str="0,8 W (29 dBm)"; break;
1363                                 default:   str="Not specified";
1364                         }
1365                 }
1366                 else
1367                         str="Not specified??";
1368
1369                 proto_tree_add_text(tf_tree,
1370                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1371                         "%s RF Power Capability, GMSK Power Class: (%u) %s", decode_bits_in_field(bit_offset, 3, value), value,str);
1372
1373                 bit_offset+=3;
1374                 curr_bits_length -= bits_needed;
1375                 oct <<= bits_needed;
1376                 bits_in_oct -= bits_needed;
1377
1378                 /*
1379                  * A5 Bits?
1380                  */
1381                 bits_needed = 1;
1382                 GET_DATA;
1383
1384                 /* analyse bits */
1385                 if ((oct>>(32-bits_needed))==0)
1386                 {
1387                         proto_tree_add_text(tf_tree,
1388                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1389                                 "A5 Bits: (%u) same values apply for parameters as in the immediately preceding Access capabilities field within this IE",oct>>(32-bits_needed));
1390                         bit_offset++;
1391                         curr_bits_length -= bits_needed;
1392                         oct <<= bits_needed;
1393                         bits_in_oct -= bits_needed;
1394                 }
1395                 else
1396                 {
1397                         int i;
1398
1399                         proto_tree_add_text(tf_tree,
1400                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1401                                 "A5 Bits: (%u) A5 bits follows",oct>>(32-bits_needed));
1402
1403                         bit_offset++;
1404                         curr_bits_length -= bits_needed;
1405                         oct <<= bits_needed;
1406                         bits_in_oct -= bits_needed;
1407                 
1408                         for (i=1; i<= 7 ; i++ )
1409                         {
1410                                 /*
1411                                  * A5 Bits decoding
1412                                  */
1413                                 bits_needed = 1;
1414                                 GET_DATA;
1415
1416                                 /* analyse bits */
1417                                 switch ( oct>>(32-bits_needed) )
1418                                 {
1419                                         case 0x00: str="encryption algorithm not available"; break;
1420                                         case 0x01: str="encryption algorithm available";     break;
1421                                         default:   str="This should not happen";
1422                                 }
1423
1424                                 proto_tree_add_text(tf_tree,
1425                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1426                                         "A5/%d: (%u) %s",i,oct>>(32-bits_needed),str);
1427                                 bit_offset++;
1428                                 curr_bits_length -= bits_needed;
1429                                 oct <<= bits_needed;
1430                                 bits_in_oct -= bits_needed;
1431                         }
1432                 }
1433
1434                 /*
1435                  * ES IND
1436                  */
1437                 bits_needed = 1;
1438                 GET_DATA;
1439
1440                 /* analyse bits */
1441                 switch ( oct>>(32-bits_needed) )
1442                 {
1443                         case 0x00: str="controlled early Classmark Sending option is not implemented"; break;
1444                         case 0x01: str="controlled early Classmark Sending option is implemented";     break;
1445                         default:   str="This should not happen";
1446                 }
1447
1448                 proto_tree_add_text(tf_tree,
1449                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1450                         "Controlled early Classmark Sending: (%u) %s",oct>>(32-bits_needed),str);
1451                 bit_offset++;
1452                 curr_bits_length -= bits_needed;
1453                 oct <<= bits_needed;
1454                 bits_in_oct -= bits_needed;
1455
1456                 /*
1457                  * PS
1458                  */
1459                 bits_needed = 1;
1460                 GET_DATA;
1461
1462                 /* analyse bits */
1463                 switch ( oct>>(32-bits_needed) )
1464                 {
1465                         case 0x00: str="PS capability not present"; break;
1466                         case 0x01: str="PS capability present";     break;
1467                         default:   str="This should not happen";
1468                 }
1469
1470                 proto_tree_add_text(tf_tree,
1471                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1472                         "Pseudo Synchronisation: (%u) %s",oct>>(32-bits_needed),str);
1473                 bit_offset++;
1474                 curr_bits_length -= bits_needed;
1475                 oct <<= bits_needed;
1476                 bits_in_oct -= bits_needed;
1477
1478                 /*
1479                  * VGCS
1480                  */
1481                 bits_needed = 1;
1482                 GET_DATA;
1483
1484                 /* analyse bits */
1485                 switch ( oct>>(32-bits_needed) )
1486                 {
1487                         case 0x00: str="no VGCS capability or no notifications wanted"; break;
1488                         case 0x01: str="VGCS capability and notifications wanted";      break;
1489                         default:   str="This should not happen";
1490                 }
1491
1492                 proto_tree_add_text(tf_tree,
1493                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1494                         "Voice Group Call Service: (%u) %s",oct>>(32-bits_needed),str);
1495                 bit_offset++;
1496                 curr_bits_length -= bits_needed;
1497                 oct <<= bits_needed;
1498                 bits_in_oct -= bits_needed;
1499
1500                 /*
1501                  * VBS
1502                  */
1503                 bits_needed = 1;
1504                 GET_DATA;
1505
1506                 /* analyse bits */
1507                 switch ( oct>>(32-bits_needed) )
1508                 {
1509                         case 0x00: str="no VBS capability or no notifications wanted"; break;
1510                         case 0x01: str="VBS capability and notifications wanted";      break;
1511                         default:   str="This should not happen";
1512                 }
1513
1514                 proto_tree_add_text(tf_tree,
1515                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1516                         "Voice Broadcast Service: (%u) %s",oct>>(32-bits_needed),str);
1517                 bit_offset++;
1518                 curr_bits_length -= bits_needed;
1519                 oct <<= bits_needed;
1520                 bits_in_oct -= bits_needed;
1521
1522                 /*
1523                  * Multislot capability?
1524                  */
1525                 bits_needed = 1;
1526                 GET_DATA;
1527
1528                 /* analyse bits */
1529                 if ((oct>>(32-bits_needed))==0)
1530                 {
1531                         proto_tree_add_text(tf_tree,
1532                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1533                                 "Multislot capability: (%u) same values apply for parameters as in the immediately preceding Access capabilities field within this IE",oct>>(32-bits_needed));
1534                         bit_offset++;
1535                         curr_bits_length -= bits_needed;
1536                         oct <<= bits_needed;
1537                         bits_in_oct -= bits_needed;
1538                 }
1539                 else
1540                 {
1541                         proto_tree_add_text(tf_tree,
1542                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1543                         "Multislot capability: (%u) Multislot capability struct available",oct>>(32-bits_needed));
1544                         bit_offset++;
1545
1546                         curr_bits_length -= bits_needed;
1547                         oct <<= bits_needed;
1548                         bits_in_oct -= bits_needed;
1549
1550                         /*
1551                          * HSCSD multislot class?
1552                          */
1553                         bits_needed = 1;
1554                         GET_DATA;
1555
1556                         /* analyse bits */
1557                         if ((oct>>(32-bits_needed))==0)
1558                         {
1559                                 proto_tree_add_text(tf_tree,
1560                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1561                                         "HSCSD multislot class: (%u) Bits are not available",oct>>(32-bits_needed));
1562                                 bit_offset++;
1563                                 curr_bits_length -= bits_needed;
1564                                 oct <<= bits_needed;
1565                                 bits_in_oct -= bits_needed;
1566                         }
1567                         else
1568                         {
1569                                 curr_bits_length -= bits_needed;
1570                                 oct <<= bits_needed;
1571                                 bits_in_oct -= bits_needed;
1572                                 bit_offset++;
1573
1574                                 /*
1575                                  * HSCSD multislot class
1576                                  */
1577                                 bits_needed = 5;
1578                                 GET_DATA;
1579
1580                                 /* analyse bits */
1581                                 proto_tree_add_text(tf_tree,
1582                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1583                                         "HSCSD multislot class: (%u) %s",oct>>(32-bits_needed),multi_slot_str[oct>>(32-bits_needed)]);
1584                                 bit_offset+=5;
1585                                 curr_bits_length -= bits_needed;
1586                                 oct <<= bits_needed;
1587                                 bits_in_oct -= bits_needed;
1588                         }
1589
1590                         /*
1591                          * GPRS multislot class?
1592                          */
1593                         bits_needed = 1;
1594                         GET_DATA;
1595
1596                         /* analyse bits */
1597                         if ((oct>>(32-bits_needed))==0)
1598                         {
1599                                 proto_tree_add_text(tf_tree,
1600                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1601                                         "GPRS multislot class: (%u) Bits are not available",oct>>(32-bits_needed));
1602                                 bit_offset++;
1603                                 curr_bits_length -= bits_needed;
1604                                 oct <<= bits_needed;
1605                                 bits_in_oct -= bits_needed;
1606                         }
1607                         else
1608                         {
1609                                 curr_bits_length -= bits_needed;
1610                                 oct <<= bits_needed;
1611                                 bits_in_oct -= bits_needed;
1612                                 bit_offset++;
1613
1614                                 /*
1615                                  * GPRS multislot class
1616                                  */
1617                                 bits_needed = 5;
1618                                 GET_DATA;
1619
1620                                 /* analyse bits */
1621                                 proto_tree_add_text(tf_tree,
1622                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1623                                         "GPRS multislot class: (%u) %s",oct>>(32-bits_needed),multi_slot_str[oct>>(32-bits_needed)]);
1624                                 bit_offset+=5;
1625                                 curr_bits_length -= bits_needed;
1626                                 oct <<= bits_needed;
1627                                 bits_in_oct -= bits_needed;
1628
1629                                 /*
1630                                  * GPRS Extended Dynamic Allocation Capability
1631                                  */
1632                                 bits_needed = 1;
1633                                 GET_DATA;
1634
1635                                 /* analyse bits */
1636                                 switch ( oct>>(32-bits_needed) )
1637                                 {
1638                                         case 0x00: str="Extended Dynamic Allocation Capability for GPRS is not implemented"; break;
1639                                         case 0x01: str="Extended Dynamic Allocation Capability for GPRS is implemented";     break;
1640                                         default:   str="This should not happen";
1641                                 }
1642                                 proto_tree_add_text(tf_tree,
1643                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1644                                         "GPRS Extended Dynamic Allocation Capability: (%u) %s",oct>>(32-bits_needed),str);
1645                                 bit_offset++;
1646                                 curr_bits_length -= bits_needed;
1647                                 oct <<= bits_needed;
1648                                 bits_in_oct -= bits_needed;
1649                         }
1650
1651                         /*
1652                          * SMS/SM values
1653                          */
1654                         bits_needed = 1;
1655                         GET_DATA;
1656
1657                         /* analyse bits */
1658                         if ((oct>>(32-bits_needed))==0)
1659                         {
1660                                 proto_tree_add_text(tf_tree,
1661                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1662                                         "SMS/SM values: (%u) Bits are not available",oct>>(32-bits_needed));
1663                                 bit_offset++;
1664                                 curr_bits_length -= bits_needed;
1665                                 oct <<= bits_needed;
1666                                 bits_in_oct -= bits_needed;
1667                         }
1668                         else
1669                         {
1670                                 curr_bits_length -= bits_needed;
1671                                 oct <<= bits_needed;
1672                                 bits_in_oct -= bits_needed;
1673                                 bit_offset++;
1674
1675                                 /*
1676                                  * Switch-Measure-Switch value
1677                                  */
1678                                 bits_needed = 4;
1679                                 GET_DATA;
1680
1681                                 /* analyse bits */
1682                                 proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_sms_value, tvb, bit_offset, 4, FALSE);
1683                                 bit_offset+=4;
1684                                 curr_bits_length -= bits_needed;
1685                                 oct <<= bits_needed;
1686                                 bits_in_oct -= bits_needed;
1687
1688                                 /*
1689                                  * Switch-Measure value
1690                                  */
1691                                 bits_needed = 4;
1692                                 GET_DATA;
1693
1694                                 /* analyse bits */
1695                                 proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_sm_value, tvb, bit_offset, 4, FALSE);
1696                                 bit_offset+=4;
1697                                 curr_bits_length -= bits_needed;
1698                                 oct <<= bits_needed;
1699                                 bits_in_oct -= bits_needed;
1700                         }
1701
1702                         /*
1703                          * ECSD multislot class?
1704                          */
1705                         bits_needed = 1;
1706                         GET_DATA;
1707
1708                         /* analyse bits */
1709                         if ((oct>>(32-bits_needed))==0)
1710                         {
1711                                 proto_tree_add_text(tf_tree,
1712                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1713                                         "ECSD multislot class: (%u) Bits are not available",oct>>(32-bits_needed));
1714                                 bit_offset++;
1715                                 curr_bits_length -= bits_needed;
1716                                 oct <<= bits_needed;
1717                                 bits_in_oct -= bits_needed;
1718                         }
1719                         else
1720                         {
1721                                 curr_bits_length -= bits_needed;
1722                                 oct <<= bits_needed;
1723                                 bits_in_oct -= bits_needed;
1724                                 bit_offset++;
1725
1726                                 /*
1727                                  * ECSD multislot class
1728                                  */
1729                                 bits_needed = 5;
1730                                 GET_DATA;
1731
1732                                 /* analyse bits */
1733                                 proto_tree_add_text(tf_tree,
1734                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1735                                         "ECSD multislot class: (%u) %s",oct>>(32-bits_needed),multi_slot_str[oct>>(32-bits_needed)]);
1736                                 bit_offset+=5;
1737                                 curr_bits_length -= bits_needed;
1738                                 oct <<= bits_needed;
1739                                 bits_in_oct -= bits_needed;
1740                         }
1741
1742                         /*
1743                          * EGPRS multislot class?
1744                          */
1745                         bits_needed = 1;
1746                         GET_DATA;
1747
1748                         /* analyse bits */
1749                         if ((oct>>(32-bits_needed))==0)
1750                         {
1751                                 proto_tree_add_text(tf_tree,
1752                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1753                                         "EGPRS multislot class: (%u) Bits are not available",oct>>(32-bits_needed));
1754                                 curr_bits_length -= bits_needed;
1755                                 oct <<= bits_needed;
1756                                 bits_in_oct -= bits_needed;
1757                                 bit_offset++;
1758                         }
1759                         else
1760                         {
1761                                 curr_bits_length -= bits_needed;
1762                                 oct <<= bits_needed;
1763                                 bits_in_oct -= bits_needed;
1764                                 bit_offset++;
1765
1766                                 /*
1767                                  * EGPRS multislot class
1768                                  */
1769                                 bits_needed = 5;
1770                                 GET_DATA;
1771
1772                                 /* analyse bits */
1773                                 proto_tree_add_text(tf_tree,
1774                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1775                                 "EGPRS multislot class: (%u) %s",oct>>(32-bits_needed),multi_slot_str[oct>>(32-bits_needed)]);
1776                                 bit_offset+=5;
1777                                 curr_bits_length -= bits_needed;
1778                                 oct <<= bits_needed;
1779                                 bits_in_oct -= bits_needed;
1780
1781                                 /*
1782                                  * EGPRS Extended Dynamic Allocation Capability
1783                                  */
1784                                 bits_needed = 1;
1785                                 GET_DATA;
1786
1787                                 /* analyse bits */
1788                                 switch ( oct>>(32-bits_needed) )
1789                                 {
1790                                         case 0x00: str="Extended Dynamic Allocation Capability for EGPRS is not implemented"; break;
1791                                         case 0x01: str="Extended Dynamic Allocation Capability for EGPRS is implemented";     break;
1792                                         default:   str="This should not happen";
1793                                 }
1794                                 proto_tree_add_text(tf_tree,
1795                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1796                                         "EGPRS Extended Dynamic Allocation Capability: (%u) %s",oct>>(32-bits_needed),str);
1797                                 bit_offset++;
1798                                 curr_bits_length -= bits_needed;
1799                                 oct <<= bits_needed;
1800                                 bits_in_oct -= bits_needed;
1801                         }
1802
1803                         /*
1804                          * DTM GPRS Multi Slot Class ?
1805                         */
1806                         bits_needed = 1;
1807                         GET_DATA;
1808
1809                         /* analyse bits */
1810                         if ((oct>>(32-bits_needed))==0)
1811                         {
1812                                 proto_tree_add_text(tf_tree,
1813                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1814                                         "DTM GPRS Multi Slot Class: (%u) Bits are not available",oct>>(32-bits_needed));
1815                                 bit_offset++;
1816                                 curr_bits_length -= bits_needed;
1817                                 oct <<= bits_needed;
1818                                 bits_in_oct -= bits_needed;
1819                         }
1820                         else
1821                         {
1822                                 curr_bits_length -= bits_needed;
1823                                 oct <<= bits_needed;
1824                                 bits_in_oct -= bits_needed;
1825                                 bit_offset++;
1826
1827                                 /*
1828                                  * DTM GPRS Multi Slot Class
1829                                  */
1830                                 bits_needed = 2;
1831                                 GET_DATA;
1832
1833                                 /* analyse bits */
1834                                 dtm_gprs_mslot = oct>>(32-bits_needed);
1835
1836                                 switch ( oct>>(32-bits_needed) )
1837                                 {
1838                                         case 0:  str="Unused. If received, the network shall interpret this as Multislot class 5"; break;
1839                                         case 1:  str="Multislot class 5 supported";  break;
1840                                         case 2:  str="Multislot class 9 supported";  break;
1841                                         case 3:  str="Multislot class 11 supported"; break;
1842                                         default: str="This should not happen";
1843                                 }
1844                 
1845                                 proto_tree_add_text(tf_tree,
1846                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1847                                         "DTM GPRS Multi Slot Class: (%u) %s",oct>>(32-bits_needed),str);
1848                                 bit_offset+=2;
1849                                 curr_bits_length -= bits_needed;
1850                                 oct <<= bits_needed;
1851                                 bits_in_oct -= bits_needed;
1852
1853                                 /*
1854                                  * Single Slot DTM
1855                                  */
1856                                 bits_needed = 1;
1857                                 GET_DATA;
1858
1859                                 /* analyse bits */
1860                                 switch ( oct>>(32-bits_needed) )
1861                                 {
1862                                         case 0x00: str="Single Slot DTM not supported"; break;
1863                                         case 0x01: str="Single Slot DTM supported";     break;
1864                                         default:   str="This should not happen";
1865                                 }
1866                                 proto_tree_add_text(tf_tree,
1867                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1868                                         "Single Slot DTM: (%u) %s",oct>>(32-bits_needed),str);
1869                                 bit_offset++;
1870                                 curr_bits_length -= bits_needed;
1871                                 oct <<= bits_needed;
1872                                 bits_in_oct -= bits_needed;
1873
1874                                 /*
1875                                  * DTM EGPRS Multi Slot Class ?
1876                                 */
1877                                 bits_needed = 1;
1878                                 GET_DATA;
1879
1880                                 /* analyse bits */
1881                                 dtm_egprs_mslot = oct>>(32-bits_needed);
1882
1883                                 if ((oct>>(32-bits_needed))==0)
1884                                 {
1885                                         proto_tree_add_text(tf_tree,
1886                                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1887                                                 "DTM EGPRS Multi Slot Class: (%u) Bits are not available",oct>>(32-bits_needed));
1888                                         bit_offset++;
1889                                         curr_bits_length -= bits_needed;
1890                                         oct <<= bits_needed;
1891                                         bits_in_oct -= bits_needed;
1892                                 }
1893                                 else
1894                                 {
1895                                         curr_bits_length -= bits_needed;
1896                                         oct <<= bits_needed;
1897                                         bits_in_oct -= bits_needed;
1898                                         bit_offset++;
1899
1900                                         /*
1901                                          * DTM EGPRS Multi Slot Class
1902                                          */
1903                                         bits_needed = 2;
1904                                         GET_DATA;
1905
1906                                         /* analyse bits */
1907                                         switch ( oct>>(32-bits_needed) )
1908                                         {
1909                                                 case 0: str="Unused. If received, the network shall interpret this as Multislot class 5"; break;
1910                                                 case 1:  str="Multislot class 5 supported";  break;
1911                                                 case 2:  str="Multislot class 9 supported";  break;
1912                                                 case 3:  str="Multislot class 11 supported"; break;
1913                                                 default: str="This should not happen";
1914                                         }
1915
1916                                         proto_tree_add_text(tf_tree,
1917                                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1918                                                 "DTM EGPRS Multi Slot Class: (%u) %s",oct>>(32-bits_needed),str);
1919                                         bit_offset+=2;
1920                                         curr_bits_length -= bits_needed;
1921                                         oct <<= bits_needed;
1922                                         bits_in_oct -= bits_needed;
1923                                 }
1924                         }
1925                 }
1926
1927                 /*
1928                  * 8PSK Power Capability?
1929                  */
1930                 bits_needed = 1;
1931                 GET_DATA;
1932
1933                 /* analyse bits */
1934                 if ((oct>>(32-bits_needed))==0)
1935                 {
1936                         proto_tree_add_text(tf_tree,
1937                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1938                                 "8PSK Power Capability: (%u) Bits are not available",oct>>(32-bits_needed));
1939                         bit_offset++;
1940                         curr_bits_length -= bits_needed;
1941                         oct <<= bits_needed;
1942                         bits_in_oct -= bits_needed;
1943                 }
1944                 else
1945                 {
1946                         curr_bits_length -= bits_needed;
1947                         oct <<= bits_needed;
1948                         bits_in_oct -= bits_needed;
1949                         bit_offset++;
1950
1951                         /*
1952                          * 8PSK Power Capability
1953                          */
1954                         bits_needed = 2;
1955                         GET_DATA;
1956
1957                         /* analyse bits */
1958                         switch ( oct>>(32-bits_needed) )
1959                         {
1960                                 case 0x00: str="Reserved";       break;
1961                                 case 0x01: str="Power class E1"; break;
1962                                 case 0x02: str="Power class E2"; break;
1963                                 case 0x03: str="Power class E3"; break;
1964                                 default:   str="This should not happen";
1965                         }
1966
1967                         proto_tree_add_text(tf_tree,
1968                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1969                                 "8PSK Power Capability: (%u) %s",oct>>(32-bits_needed),str);
1970                         bit_offset+=2;
1971                         curr_bits_length -= bits_needed;
1972                         oct <<= bits_needed;
1973                         bits_in_oct -= bits_needed;
1974                 }
1975
1976                 /*
1977                  * COMPACT Interference Measurement Capability
1978                  */
1979                 bits_needed = 1;
1980                 GET_DATA;
1981
1982                 /* analyse bits */
1983                 switch ( oct>>(32-bits_needed) )
1984                 {
1985                         case 0x00: str="COMPACT Interference Measurement Capability is not implemented"; break;
1986                         case 0x01: str="COMPACT Interference Measurement Capability is implemented";     break;
1987                         default:   str="This should not happen";
1988                 }
1989
1990                 proto_tree_add_text(tf_tree,
1991                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
1992                         "COMPACT Interference Measurement Capability: (%u) %s",oct>>(32-bits_needed),str);
1993                 bit_offset++;
1994                 curr_bits_length -= bits_needed;
1995                 oct <<= bits_needed;
1996                 bits_in_oct -= bits_needed;
1997
1998                 /*
1999                  * Revision Level Indicator
2000                  */
2001                 bits_needed = 1;
2002                 GET_DATA;
2003
2004                 /* analyse bits */
2005                 switch ( oct>>(32-bits_needed) )
2006                 {
2007                         case 0x00: str="The ME is Release 98 or older"; break;
2008                         case 0x01: str="The ME is Release 99 onwards";  break;
2009                         default:   str="This should not happen";
2010                 }
2011
2012                 proto_tree_add_text(tf_tree,
2013                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
2014                         "Revision Level Indicator: (%u) %s",oct>>(32-bits_needed),str);
2015                 bit_offset++;
2016                 curr_bits_length -= bits_needed;
2017                 oct <<= bits_needed;
2018                 bits_in_oct -= bits_needed;
2019
2020                 /*
2021                  * UMTS FDD Radio Access Technology Capability
2022                  */
2023                 bits_needed = 1;
2024                 GET_DATA;
2025
2026                 /* analyse bits */
2027                 switch ( oct>>(32-bits_needed) )
2028                 {
2029                         case 0x00: str="UMTS FDD not supported"; break;
2030                         case 0x01: str="UMTS FDD supported";     break;
2031                         default:   str="This should not happen";
2032                 }
2033
2034                 proto_tree_add_text(tf_tree,
2035                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
2036                         "UMTS FDD Radio Access Technology Capability: (%u) %s",oct>>(32-bits_needed),str);
2037                 bit_offset++;
2038                 curr_bits_length -= bits_needed;
2039                 oct <<= bits_needed;
2040                 bits_in_oct -= bits_needed;
2041
2042                 /*
2043                  * UMTS 3.84 Mcps TDD Radio Access Technology Capability
2044                  */
2045                 bits_needed = 1;
2046                 GET_DATA;
2047
2048         /* analyse bits */
2049                 switch ( oct>>(32-bits_needed) )
2050                 {
2051                         case 0x00: str="UMTS 3.84 Mcps TDD not supported"; break;
2052                         case 0x01: str="UMTS 3.84 Mcps TDD supported";     break;
2053                         default:   str="This should not happen";
2054                 }
2055
2056                 proto_tree_add_text(tf_tree,
2057                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
2058                         "UMTS 3.84 Mcps TDD Radio Access Technology Capability: (%u) %s",oct>>(32-bits_needed),str);
2059                 bit_offset++;
2060                 curr_bits_length -= bits_needed;
2061                 oct <<= bits_needed;
2062                 bits_in_oct -= bits_needed;
2063
2064                 /*
2065                  * CDMA 2000 Radio Access Technology Capability
2066                  */
2067                 bits_needed = 1;
2068                 GET_DATA;
2069
2070                 /* analyse bits */
2071                 switch ( oct>>(32-bits_needed) )
2072                 {
2073                         case 0x00: str="CDMA 2000 not supported"; break;
2074                         case 0x01: str="CDMA 2000 supported";     break;
2075                         default:   str="This should not happen";
2076                 }
2077
2078                 proto_tree_add_text(tf_tree,
2079                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
2080                         "CDMA 2000 Radio Access Technology Capability: (%u) %s",oct>>(32-bits_needed),str);
2081                 bit_offset++;
2082                 curr_bits_length -= bits_needed;
2083                 oct <<= bits_needed;
2084                 bits_in_oct -= bits_needed;
2085
2086                 /*
2087                  * UMTS 1.28 Mcps TDD Radio Access Technology Capability
2088                  */
2089                 bits_needed = 1;
2090                 GET_DATA;
2091
2092                 /* analyse bits */
2093                 switch ( oct>>(32-bits_needed) )
2094                 {
2095                         case 0x00: str="UMTS 1.28 Mcps TDD not supported"; break;
2096                         case 0x01: str="UMTS 1.28 Mcps TDD supported";     break;
2097                         default:   str="This should not happen";
2098                 }
2099
2100                 proto_tree_add_text(tf_tree,
2101                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
2102                         "UMTS 1.28 Mcps TDD Radio Access Technology Capability: (%u) %s",oct>>(32-bits_needed),str);
2103                 bit_offset++;
2104                 curr_bits_length -= bits_needed;
2105                 oct <<= bits_needed;
2106                 bits_in_oct -= bits_needed;
2107
2108                 /*
2109                  * GERAN Feature Package 1
2110                  */
2111                 bits_needed = 1;
2112                 GET_DATA;
2113
2114                 /* analyse bits */
2115                 switch ( oct>>(32-bits_needed) )
2116                 {
2117                         case 0x00: str="GERAN feature package 1 not supported"; break;
2118                         case 0x01: str="GERAN feature package 1 supported";     break;
2119                         default:   str="This should not happen";
2120                 }
2121
2122                 proto_tree_add_text(tf_tree,
2123                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
2124                 "GERAN Feature Package 1: (%u) %s",oct>>(32-bits_needed),str);
2125                 bit_offset++;
2126                 curr_bits_length -= bits_needed;
2127                 oct <<= bits_needed;
2128                 bits_in_oct -= bits_needed;
2129
2130                 /*
2131                  * Extended DTM (E)GPRS Multi Slot Class
2132                  */
2133                 bits_needed = 1;
2134                 GET_DATA;
2135
2136                 /* analyse bits */
2137                 if ((oct>>(32-bits_needed))==0)
2138                 {
2139                         proto_tree_add_text(tf_tree,
2140                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
2141                                 "Extended DTM (E)GPRS Multi Slot Class: (%u) Bits are not available",oct>>(32-bits_needed));
2142                         curr_bits_length -= bits_needed;
2143                         oct <<= bits_needed;
2144                         bits_in_oct -= bits_needed;
2145                         bit_offset++;
2146                 }
2147                 else
2148                 {
2149                         curr_bits_length -= bits_needed;
2150                         oct <<= bits_needed;
2151                         bits_in_oct -= bits_needed;
2152
2153                         /*
2154                          * Extended DTM GPRS Multi Slot Class
2155                          */
2156                         bits_needed = 2;
2157                         GET_DATA;
2158
2159                         /* analyse bits */
2160                         switch ( (oct>>(32-bits_needed))|(dtm_gprs_mslot<<4) )
2161                         {
2162                                 case 0x00: str="Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
2163                                 case 0x01: str="Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
2164                                 case 0x02: str="Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
2165                                 case 0x03: str="Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
2166                                 case 0x10: str="Multislot class 5 supported";  break;
2167                                 case 0x11: str="Multislot class 6 supported";  break;
2168                                 case 0x12: str="Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
2169                                 case 0x13: str="Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
2170                                 case 0x20: str="Multislot class 9 supported";  break;
2171                                 case 0x21: str="Multislot class 10 supported"; break;
2172                                 case 0x22: str="Unused. If received, it shall be interpreted as Multislot class 9 supported";  break;
2173                                 case 0x23: str="Unused. If received, it shall be interpreted as Multislot class 9 supported";  break;
2174                                 case 0x30: str="Multislot class 11 supported"; break;
2175                                 case 0x31: str="Unused. If received, it shall be interpreted as Multislot class 11 supported"; break;
2176                                 case 0x32: str="Unused. If received, it shall be interpreted as Multislot class 11 supported"; break;
2177                                 case 0x33: str="Unused. If received, it shall be interpreted as Multislot class 11 supported"; break;
2178                                 default:   str="This should not happen";
2179                         }
2180
2181                         proto_tree_add_text(tf_tree,
2182                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
2183                                 "Extended DTM GPRS Multi Slot Class: (%u) %s",oct>>(32-bits_needed),str);
2184                         bit_offset+=2;
2185                         curr_bits_length -= bits_needed;
2186                         oct <<= bits_needed;
2187                         bits_in_oct -= bits_needed;
2188
2189                         if ( dtm_egprs_mslot <= 3 )
2190                         {
2191                                 /*
2192                                  * Extended DTM EGPRS Multi Slot Class
2193                                  */
2194                                 bits_needed = 2;
2195                                 GET_DATA;
2196
2197                                 /* analyse bits */
2198                                 switch ( (oct>>(32-bits_needed))|(dtm_egprs_mslot<<4) )
2199                                 {
2200                                         case 0x00: str="Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
2201                                         case 0x01: str="Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
2202                                         case 0x02: str="Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
2203                                         case 0x03: str="Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
2204                                         case 0x10: str="Multislot class 5 supported";  break;
2205                                         case 0x11: str="Multislot class 6 supported";  break;
2206                                         case 0x12: str="Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
2207                                         case 0x13: str="Unused. If received, it shall be interpreted as Multislot class 5 supported";  break;
2208                                         case 0x20: str="Multislot class 9 supported";  break;
2209                                         case 0x21: str="Multislot class 10 supported"; break;
2210                                         case 0x22: str="Unused. If received, it shall be interpreted as Multislot class 9 supported";  break;
2211                                         case 0x23: str="Unused. If received, it shall be interpreted as Multislot class 9 supported";  break;
2212                                         case 0x30: str="Multislot class 11 supported"; break;
2213                                         case 0x31: str="Unused. If received, it shall be interpreted as Multislot class 11 supported"; break;
2214                                         case 0x32: str="Unused. If received, it shall be interpreted as Multislot class 11 supported"; break;
2215                                         case 0x33: str="Unused. If received, it shall be interpreted as Multislot class 11 supported"; break;
2216                                         default:   str="This should not happen";
2217                                 }
2218
2219                                 proto_tree_add_text(tf_tree,
2220                                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
2221                                         "Extended DTM EGPRS Multi Slot Class: (%u) %s",oct>>(32-bits_needed),str);
2222                                 bit_offset+=2;
2223                                 curr_bits_length -= bits_needed;
2224                                 oct <<= bits_needed;
2225                                 bits_in_oct -= bits_needed;
2226                         }
2227                 }
2228
2229                 /*
2230                  * Modulation based multislot class support
2231                  */
2232                 bits_needed = 1;
2233                 GET_DATA;
2234
2235                 /* analyse bits */
2236                 switch ( oct>>(32-bits_needed) )
2237                 {
2238                         case 0x00: str="Modulation based multislot class not supported"; break;
2239                         case 0x01: str="Modulation based multislot class supported";     break;
2240                         default:   str="This should not happen";
2241                 }
2242
2243                 proto_tree_add_text(tf_tree,
2244                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
2245                         "Modulation based multislot class support: (%u) %s",oct>>(32-bits_needed),str);
2246                 bit_offset++;
2247                 curr_bits_length -= bits_needed;
2248                 oct <<= bits_needed;
2249                 bits_in_oct -= bits_needed;
2250
2251                 /*
2252                  * High Multislot Capability
2253                  */
2254                 bits_needed = 1;
2255                 GET_DATA;
2256
2257                 /* analyse bits */
2258                 if ((oct>>(32-bits_needed))==0)
2259                 {
2260                         proto_tree_add_text(tf_tree,
2261                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
2262                                 "High Multislot Capability: (%u) Bits are not available",oct>>(32-bits_needed));
2263                         bit_offset++;
2264                         curr_bits_length -= bits_needed;
2265                         oct <<= bits_needed;
2266                         bits_in_oct -= bits_needed;
2267                 }
2268                 else
2269                 {
2270                         curr_bits_length -= bits_needed;
2271                         oct <<= bits_needed;
2272                         bits_in_oct -= bits_needed;
2273                         bit_offset++;
2274
2275                         /*
2276                          * High Multislot Capability
2277                          */
2278                         bits_needed = 2;
2279                         GET_DATA;
2280
2281                         /* analyse bits */
2282                         proto_tree_add_text(tf_tree,
2283                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
2284                                             "High Multislot Capability: 0x%02x (%u)"
2285                                             " - This field effect all other multislot fields."
2286                                             " To understand the value please read TS 24.008 5.6.0"
2287                                             " Release 5 Chap 10.5.5.12 Page 406",
2288                                             oct>>(32-bits_needed),
2289                                             oct>>(32-bits_needed));
2290                         bit_offset+=2;
2291                         curr_bits_length -= bits_needed;
2292                         oct <<= bits_needed;
2293                         bits_in_oct -= bits_needed;
2294                 }
2295
2296                 /*
2297                  * GERAN Iu Mode Capability
2298                  */
2299                 bits_needed = 1;
2300                 GET_DATA;
2301
2302                 /* analyse bits */
2303                 switch ( oct>>(32-bits_needed) )
2304                 {
2305                         case 0x00: str="GERAN Iu mode not supported"; break;
2306                         case 0x01: str="GERAN Iu mode supported";     break;
2307                         default:   str="This should not happen";
2308                 }
2309
2310                 proto_tree_add_text(tf_tree,
2311                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
2312                         "GERAN Iu Mode Capability: (%u) %s",oct>>(32-bits_needed),str);
2313                 bit_offset++;
2314                 curr_bits_length -= bits_needed;
2315                 oct <<= bits_needed;
2316                 bits_in_oct -= bits_needed;
2317
2318                 /*
2319                  * GMSK/8-PSK Multislot Power Profile
2320                  */
2321                 bits_needed = 1;
2322                 GET_DATA;
2323
2324                 /* analyse bits */
2325                 if ((oct>>(32-bits_needed))==0)
2326                 {
2327                         proto_tree_add_text(tf_tree,
2328                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
2329                                 "GMSK/8-PSK Multislot Power Profile: (%u) Bits are not available",oct>>(32-bits_needed));
2330                         bit_offset++;
2331                         curr_bits_length -= bits_needed;
2332                         oct <<= bits_needed;
2333                         bits_in_oct -= bits_needed;
2334                 }
2335                 else
2336                 {
2337                         curr_bits_length -= bits_needed;
2338                         oct <<= bits_needed;
2339                         bits_in_oct -= bits_needed;
2340                         bit_offset++;
2341
2342                         /*
2343                          * GMSK Multislot Power Profile
2344                          */
2345                         bits_needed = 2;
2346                         GET_DATA;
2347
2348                         /* analyse bits */
2349                         switch ( oct>>(32-bits_needed) )
2350                         {
2351                                 case 0x00: str="GMSK_MULTISLOT_POWER_PROFILE 0"; break;
2352                                 case 0x01: str="GMSK_MULTISLOT_POWER_PROFILE 1"; break;
2353                                 case 0x02: str="GMSK_MULTISLOT_POWER_PROFILE 2"; break;
2354                                 case 0x03: str="GMSK_MULTISLOT_POWER_PROFILE 3"; break;
2355                                 default:   str="This should not happen";
2356                         }
2357         
2358                         proto_tree_add_text(tf_tree,
2359                                 tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
2360                                 "GMSK Multislot Power Profile: (%u) %s",oct>>(32-bits_needed),str);
2361                         bit_offset+=2;
2362                         curr_bits_length -= bits_needed;
2363                         oct <<= bits_needed;
2364                         bits_in_oct -= bits_needed;
2365
2366                         /*
2367                          * 8-PSK Multislot Power Profile
2368                          */
2369                         bits_needed = 2;
2370                         GET_DATA;
2371
2372                         /* analyse bits */
2373                         switch ( oct>>(32-bits_needed) )
2374                         {
2375                                 case 0x00: str="8-PSK_MULTISLOT_POWER_PROFILE 0"; break;
2376                                 case 0x01: str="8-PSK_MULTISLOT_POWER_PROFILE 1"; break;
2377                                 case 0x02: str="8-PSK_MULTISLOT_POWER_PROFILE 2"; break;
2378                                 case 0x03: str="8-PSK_MULTISLOT_POWER_PROFILE 3"; break;
2379                                 default:   str="This should not happen";
2380                         }
2381         
2382                         proto_tree_add_text(tf_tree,
2383                         tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
2384                         "8-PSK Multislot Power Profile: (%u) %s",oct>>(32-bits_needed),str);
2385                         bit_offset+=2;
2386                         curr_bits_length -= bits_needed;
2387                         oct <<= bits_needed;
2388                         bits_in_oct -= bits_needed;
2389
2390                 }
2391
2392                 /*
2393                  * we are too long ... so jump over it
2394                  */
2395                 while ( curr_bits_length > 0 )
2396                 {
2397                         if ( curr_bits_length > 8 )
2398                                 bits_needed = 8;
2399                         else
2400                                 bits_needed = curr_bits_length;
2401                         GET_DATA;
2402                         curr_bits_length -= bits_needed;
2403                         oct <<= bits_needed;
2404                         bits_in_oct -= bits_needed;
2405                 }
2406
2407         } while ( 1 );
2408
2409         curr_offset+= curr_len;
2410            
2411         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2412
2413         return(curr_offset - offset);
2414 }
2415
2416 /*
2417  * [9] 10.5.5.14
2418  */
2419 static const range_string gmm_cause_vals[] = {
2420         { 0x00, 0x01, "Protocol error, unspecified(Not def in v8.6.0)"},
2421         { 0x02, 0x02, "IMSI unknown in HLR"},
2422         { 0x03, 0x03, "Illegal MS"},
2423         { 0x04, 0x04, "IMSI unknown in VLR"}, /* Annex G.1 */
2424         { 0x05, 0x05, "IMEI not accepted"}, /* Annex G.1 */
2425         { 0x06, 0x06, "Illegal ME"},
2426         { 0x07, 0x07, "GPRS services not allowed"},
2427         { 0x08, 0x08, "GPRS services and non-GPRS services not allowed"},
2428         { 0x09, 0x09, "MS identity cannot be derived by the network"},
2429         { 0x0a, 0x0a, "Implicitly detached"},
2430         { 0x0b, 0x0b, "PLMN not allowed"},
2431         { 0x0c, 0x0c, "Location Area not allowed"},
2432         { 0x0d, 0x0d, "Roaming not allowed in this location area"},
2433         { 0x0e, 0x0e, "GPRS services not allowed in this PLMN"},
2434         { 0x0f, 0x0f, "No Suitable Cells In Location Area"},
2435         { 0x10, 0x10, "MSC temporarily not reachable"},
2436         { 0x11, 0x11, "Network failure"},
2437         { 0x12, 0x13, "Protocol error, unspecified(Not def in v8.6.0)"},
2438         { 0x14, 0x14, "MAC failure"},
2439         { 0x15, 0x15, "Synch failure"},
2440         { 0x16, 0x16, "Congestion"},
2441         { 0x17, 0x17, "GSM authentication unacceptable"},
2442         { 0x18, 0x18, "Protocol error, unspecified(Not def in v8.6.0)"},
2443         { 0x19, 0x19, "Not authorized for this CSG"},
2444         { 0x20, 0x20, "Service option not supported"},                                          /* Annex G.4 */
2445         { 0x21, 0x21, "Requested service option not subscribed"},                       /* Annex G.4 */
2446         { 0x22, 0x22, "Service option temporarily out of order"},                       /* Annex G.4 */
2447
2448         { 0x23, 0x25, "Protocol error, unspecified(Not def in v8.6.0)"},
2449
2450         { 0x26, 0x26, "Call cannot be identified(non-GPRS services only)"},     /* Annex G.4 */
2451         { 0x27, 0x27, "Protocol error, unspecified(Not def in v8.6.0)"},
2452         { 0x28, 0x28, "No PDP context activated"},
2453         { 0x29, 0x2f, "Protocol error, unspecified(Not def in v8.6.0)"},
2454         { 0x30, 0x3f, "Retry upon entry into a new cell"},
2455
2456         { 0x40, 0x5e, "Protocol error, unspecified(Not def in v8.6.0)"},
2457
2458         { 0x5f, 0x5f, "Semantically incorrect message"},
2459         { 0x60, 0x60, "Invalid mandatory information"},
2460         { 0x61, 0x61, "Message type non-existent or not implemented"},
2461         { 0x62, 0x62, "Message type not compatible with the protocol state"},
2462         { 0x63, 0x63, "Information element non-existent or notimplemented"},
2463         { 0x64, 0x64, "Conditional IE error"},
2464         { 0x65, 0x65, "Message not compatible with the protocol state"},
2465
2466         { 0x66, 0x6e, "Protocol error, unspecified(Not def in v8.6.0)"},
2467
2468         { 0x6f, 0x6f, "Protocol error, unspecified"},
2469         { 0x70, 0xff, "Protocol error, unspecified(Not def in v8.6.0)"},
2470         { 0, 0, NULL }
2471 };
2472 /* NOTE 1 TS 124 008 V8.6.0 (2009-07) 
2473         "Any other value received by the mobile station shall be treated as 0110 1111, "Protocol
2474         error, unspecified". Any other value received by the network shall be treated as
2475         0110 1111, "Protocol error, unspecified".
2476  */
2477
2478 /* NOTE: The listed reject cause values are defined in annex G. */
2479
2480 static guint16
2481 de_gmm_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2482 {
2483         guint32       curr_offset;
2484
2485         curr_offset = offset;
2486
2487         proto_tree_add_item(tree, hf_gsm_a_gm_cause, tvb, curr_offset, 1, FALSE);
2488
2489         curr_offset++;
2490
2491         /* no length check possible */
2492
2493         return(curr_offset - offset);
2494 }
2495
2496 /*
2497  * [7] 10.5.5.15 Routing area identification
2498  */
2499 guint16
2500 de_gmm_rai(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2501 {
2502         proto_tree   *subtree;
2503         proto_item   *item;
2504         guint32       mcc;
2505         guint32       mnc;
2506         guint32       lac;
2507         guint32       rac;
2508         guint32       curr_offset;
2509
2510         curr_offset = offset;
2511
2512         mcc = (tvb_get_guint8(tvb, curr_offset) & 0x0f) <<8;
2513         mcc |= (tvb_get_guint8(tvb, curr_offset) & 0xf0);
2514         mcc |= (tvb_get_guint8(tvb, curr_offset+1) & 0x0f);
2515         mnc = (tvb_get_guint8(tvb, curr_offset+2) & 0x0f) <<8;
2516         mnc |= (tvb_get_guint8(tvb, curr_offset+2) & 0xf0);
2517         mnc |= (tvb_get_guint8(tvb, curr_offset+1) & 0xf0) >>4;
2518         if ((mnc&0x000f) == 0x000f)
2519                  mnc = mnc>>4;
2520
2521         lac = tvb_get_guint8(tvb, curr_offset+3);
2522         lac <<= 8;
2523         lac |= tvb_get_guint8(tvb, curr_offset+4);
2524         rac = tvb_get_guint8(tvb, curr_offset+5);
2525
2526         item = proto_tree_add_text(tree,
2527                 tvb, curr_offset, 6,
2528                 "Routing area identification: %x-%x-%x-%x",
2529                 mcc,mnc,lac,rac);
2530
2531         subtree = proto_item_add_subtree(item, ett_gmm_rai);
2532         dissect_e212_mcc_mnc(tvb, subtree, offset);
2533         curr_offset+=6;
2534
2535         /* no length check possible */
2536
2537         return(curr_offset - offset);
2538 }
2539
2540 /*
2541  * [7] 10.5.5.17
2542  */
2543 static guint16
2544 de_gmm_update_res(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2545 {
2546         guint8        oct;
2547         guint32       curr_offset;
2548         const gchar  *str;
2549
2550         curr_offset = offset;
2551
2552         oct = tvb_get_guint8(tvb, curr_offset);
2553
2554         /* IMPORTANT - IT'S ASSUMED THAT THE INFORMATION IS IN THE HIGHER NIBBLE */
2555         oct >>= 4;
2556
2557         switch(oct&7)
2558         {
2559                 case 0:  str="RA updated";              break;
2560                 case 1:  str="combined RA/LA updated";  break;
2561                 default: str="reserved";
2562         }
2563
2564         proto_tree_add_text(tree,
2565                 tvb, curr_offset, 1,
2566                 "Update Result: (%u) %s",
2567                 oct&7,
2568                 str);
2569
2570         curr_offset++;
2571
2572         /* no length check possible */
2573
2574         return(curr_offset - offset);
2575 }
2576
2577 /*
2578  * [9] 10.5.5.18 Update Type
2579  */
2580 static const value_string gsm_a_gm_update_type_vals[] = {
2581         { 0x00, "RA updating" },
2582         { 0x01, "combined RA/LA updating" },
2583         { 0x02, "combined RA/LA updating with IMSI attach" },
2584         { 0x03, "Periodic updating" },
2585         { 0, NULL }
2586 };
2587
2588 static guint16
2589 de_gmm_update_type(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2590 {
2591         proto_item   *tf = NULL;
2592         proto_tree   *tf_tree = NULL;
2593
2594         proto_tree_add_bits_item(tree, hf_gsm_a_gm_ciph_key_seq_num, tvb, offset << 3, 4, FALSE);
2595
2596         tf = proto_tree_add_text(tree,
2597                 tvb, offset, 1,
2598                 "Update Type");
2599
2600         tf_tree = proto_item_add_subtree(tf, ett_gmm_update_type );
2601
2602         proto_tree_add_item(tf_tree, hf_gsm_a_gm_for, tvb, offset, 1, FALSE);
2603         proto_tree_add_item(tf_tree, hf_gsm_a_gm_update_type, tvb, offset, 1, FALSE);
2604
2605         /* no length check possible */
2606         return(1);
2607 }
2608
2609 /*
2610  * [9] 10.5.5.19 A&C reference number (lower nibble)
2611  */
2612 static guint16
2613 de_gmm_ac_ref_nr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2614 {
2615         /* IMPORTANT - IT'S ASSUMED THAT THE INFORMATION IS IN THE LOWER NIBBLE */
2616         proto_tree_add_bits_item(tree, hf_gsm_a_gm_ac_ref_nr, tvb, (offset << 3) + 4, 4, FALSE);
2617
2618         /* no length check possible */
2619         return(1);
2620 }
2621
2622 /*
2623  * [9] 10.5.5.19 A&C reference number (higher nibble)
2624  */
2625 static guint16
2626 de_gmm_ac_ref_nr_h(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2627 {
2628         /* IMPORTANT - IT'S ASSUMED THAT THE INFORMATION IS IN THE HIGHER NIBBLE */
2629         proto_tree_add_bits_item(tree, hf_gsm_a_gm_ac_ref_nr, tvb, offset << 3, 4, FALSE);
2630
2631         /* no length check possible */
2632         return(1);
2633 }
2634
2635 /*
2636  * [9] 10.5.5.20 Service type
2637  */
2638 static const value_string gsm_a_gm_serv_type_vals[] = {
2639         { 0x00, "Signalling" },
2640         { 0x01, "Data" },
2641         { 0x02, "Paging response" },
2642         { 0x03, "MBMS Multicast Service Reception" },
2643         { 0x04, "MBMS Broadcast Service Reception" },
2644         { 0, NULL }
2645 };
2646
2647 static guint16
2648 de_gmm_service_type(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2649 {
2650         guint32 bit_offset;
2651
2652         bit_offset = offset << 3;
2653         proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, bit_offset, 1, FALSE);
2654         bit_offset += 1;
2655         proto_tree_add_bits_item(tree, hf_gsm_a_gm_serv_type, tvb, bit_offset, 3, FALSE);
2656         bit_offset += 3;
2657         proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, bit_offset, 1, FALSE);
2658         bit_offset += 1;
2659         proto_tree_add_bits_item(tree, hf_gsm_a_gm_ciph_key_seq_num, tvb, bit_offset, 3, FALSE);
2660
2661         /* no length check possible */
2662         return(1);
2663 }
2664
2665 /*
2666  * [9] 10.5.5.21 Cell Notification
2667  * No data
2668  */
2669
2670 /*
2671  * [7] 10.5.5.22
2672  */
2673 static guint16
2674 de_gmm_ps_lcs_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2675 {
2676         guint8  oct;
2677         guint32 curr_offset;
2678
2679         static const gchar *str_otd[2]={
2680                 "MS assisted E-OTD not supported",
2681                 "MS assisted E-OTD supported" };
2682         static const gchar *str_gps[2]={
2683                 "MS assisted GPS not supported",
2684                 "MS assisted GPS supported" };
2685
2686         curr_offset = offset;
2687
2688         oct = tvb_get_guint8(tvb, curr_offset);
2689
2690         oct <<=3;   /* move away the spare bits */
2691
2692         proto_tree_add_text(tree,
2693                 tvb, curr_offset, 1,
2694                 "OTD-A: (%u) %s",
2695                 oct>>7,
2696                 str_otd[oct>>7]);
2697                 oct <<=1;
2698         proto_tree_add_text(tree,
2699                 tvb, curr_offset, 1,
2700                 "OTD-B: (%u) %s",
2701                 oct>>7,
2702                 str_otd[oct>>7]);
2703                 oct <<=1;
2704
2705         proto_tree_add_text(tree,
2706                 tvb, curr_offset, 1,
2707                 "GPS-A: (%u) %s",
2708                 oct>>7,
2709                 str_gps[oct>>7]);
2710                 oct <<=1;
2711         proto_tree_add_text(tree,
2712                 tvb, curr_offset, 1,
2713                 "GPS-B: (%u) %s",
2714                 oct>>7,
2715                 str_gps[oct>>7]);
2716                 oct <<=1;
2717         proto_tree_add_text(tree,
2718                 tvb, curr_offset, 1,
2719                 "GPS-C: (%u) %s",
2720                 oct>>7,
2721                 str_gps[oct>>7]);
2722
2723         curr_offset++;
2724
2725         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2726
2727         return(curr_offset - offset);
2728 }
2729
2730 /*
2731  * [7] 10.5.5.23
2732  */
2733 static guint16
2734 de_gmm_net_feat_supp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2735 {
2736         guint8  oct;
2737         guint32 curr_offset;
2738         const gchar     *str;
2739
2740         curr_offset = offset;
2741
2742         oct = tvb_get_guint8(tvb, curr_offset);
2743
2744         switch(oct&8)
2745         {
2746                 case 8: str="LCS-MOLR via PS domain not supported"; break;
2747                 default: str="LCS-MOLR via PS domain supported";
2748         }
2749
2750         proto_tree_add_text(tree,
2751                 tvb, curr_offset, 1,
2752                 "Network Feature Support: (%u) %s",
2753                 (oct>>3)&1,
2754                 str);
2755
2756         curr_offset++;
2757
2758         /* no length check possible */
2759
2760         return(curr_offset - offset);
2761 }
2762
2763 /* [7] 10.5.5.24 Inter RAT information container */
2764 static guint16
2765 de_gmm_rat_info_container(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2766 {
2767         guint32 curr_offset;
2768         tvbuff_t *rrc_irat_ho_info_tvb;
2769
2770         curr_offset = offset;
2771
2772 /* The value part of the Inter RAT information container information element is the INTER RAT HANDOVER INFO as
2773 defined in 3GPP TS 25.331 [23c]. If this field includes padding bits, they are defined in 3GPP TS 25.331 [23c].*/
2774         rrc_irat_ho_info_tvb = tvb_new_subset(tvb, curr_offset, len, len);
2775         if (rrc_irat_ho_info_handle)
2776                 call_dissector(rrc_irat_ho_info_handle, rrc_irat_ho_info_tvb, gsm_a_dtap_pinfo , tree);
2777         else
2778                 proto_tree_add_text(tree, tvb, curr_offset, len,"INTER RAT HANDOVER INFO - Not decoded");
2779
2780         return len;
2781
2782 }
2783
2784 /*
2785  * [7] 10.5.7.1
2786  */
2787 static guint16
2788 de_gc_context_stat(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2789 {
2790         guint8  oct;
2791         guint16 pdp_nr;
2792         guint32 curr_offset;
2793         proto_item  *tf = NULL;
2794         proto_tree  *tf_tree = NULL;
2795
2796         curr_offset = offset;
2797
2798         oct = tvb_get_guint8(tvb, curr_offset);
2799
2800         tf = proto_tree_add_text(tree,
2801                 tvb, curr_offset, 1,
2802                 "PDP Context Status");
2803
2804         tf_tree = proto_item_add_subtree(tf, ett_gmm_context_stat );
2805
2806         oct = tvb_get_guint8(tvb, curr_offset);
2807
2808         for ( pdp_nr=0;pdp_nr<16; pdp_nr++ )
2809         {
2810                 if ( pdp_nr == 8 )
2811                 {
2812                         curr_offset++;
2813                         oct = tvb_get_guint8(tvb, curr_offset);
2814                 }
2815                 proto_tree_add_text(tf_tree,
2816                         tvb, curr_offset, 1,
2817                         "NSAPI %d: (%u) %s",pdp_nr,
2818                         oct&1,
2819                         pdp_str[oct&1]);
2820                 oct>>=1;
2821         }
2822
2823         curr_offset++;
2824
2825         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2826
2827         return(curr_offset - offset);
2828 }
2829
2830 /*
2831  * [7] 10.5.7.2
2832  */
2833 static guint16
2834 de_gc_radio_prio(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2835 {
2836         guint8  oct;
2837         guint32 curr_offset;
2838         const gchar     *str;
2839
2840         curr_offset = offset;
2841
2842         oct = tvb_get_guint8(tvb, curr_offset);
2843
2844         switch ( oct&7 )
2845         {
2846                 case 1: str="priority level 1 (highest)"; break;
2847                 case 2: str="priority level 2"; break;
2848                 case 3: str="priority level 3"; break;
2849                 case 4: str="priority level 4 (lowest)"; break;
2850                 default: str="priority level 4 (lowest)";
2851         }
2852
2853         proto_tree_add_text(tree,
2854                 tvb, curr_offset, 1,
2855                 "Radio Priority (PDP or SMS): (%u) %s",
2856                 oct&7,
2857                 str);
2858
2859         curr_offset++;
2860
2861         return(curr_offset - offset);
2862 }
2863
2864 /*
2865  * [7] 10.5.7.3
2866  */
2867 static guint16
2868 de_gc_timer(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2869 {
2870         guint8  oct;
2871         guint16 val;
2872         guint32 curr_offset;
2873         const gchar     *str;
2874
2875         curr_offset = offset;
2876
2877         oct = tvb_get_guint8(tvb, curr_offset);
2878
2879         val = oct&0x1f;
2880
2881         switch(oct>>5)
2882         {
2883                 case 0: str="sec"; val*=2; break;
2884                 case 1: str="min"; break;
2885                 case 2: str="min"; val*=6; break;
2886                 case 7:
2887                         proto_tree_add_text(tree,
2888                                 tvb, curr_offset, 1,
2889                                 "GPRS Timer: timer is deactivated");
2890
2891                 default: str="min";
2892         }
2893
2894         proto_tree_add_text(tree,
2895                 tvb, curr_offset, 1,
2896                 "GPRS Timer: (%u) %u %s",
2897                 oct, val,
2898                 str);
2899
2900         curr_offset++;
2901
2902         /* no length check possible */
2903
2904         return(curr_offset - offset);
2905 }
2906
2907 /*
2908  * [7] 10.5.7.4
2909  */
2910 static guint16
2911 de_gc_timer2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len _U_)
2912 {
2913         guint8  oct;
2914         guint16 val;
2915         guint32 curr_offset;
2916         const gchar     *str;
2917
2918         curr_offset = offset;
2919
2920         oct = tvb_get_guint8(tvb, curr_offset);
2921
2922         val = oct&0x1f;
2923
2924         switch(oct>>5)
2925         {
2926                 case 0: str="sec"; val*=2; break;
2927                 case 1: str="min"; break;
2928                 case 2: str="min"; val*=6; break;
2929                 case 7:
2930                         proto_tree_add_text(tree,
2931                         tvb, curr_offset, 1,
2932                         "GPRS Timer: timer is deactivated");
2933
2934                 default: str="min";
2935         }
2936
2937         proto_tree_add_text(tree,
2938                 tvb, curr_offset, 1,
2939                 "GPRS Timer: (%u) %u %s %s",
2940                 oct, val,
2941                 str, add_string ? add_string : "");
2942
2943         curr_offset++;
2944
2945         return(curr_offset - offset);
2946 }
2947
2948 /*
2949  * [7] 10.5.7.5
2950  */
2951 static guint16
2952 de_gc_radio_prio2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2953 {
2954         guint8  oct;
2955         guint32 curr_offset;
2956         const gchar     *str;
2957
2958         curr_offset = offset;
2959
2960         oct = tvb_get_guint8(tvb, curr_offset);
2961
2962         /* IMPORTANT - IT'S ASSUMED THAT THE INFORMATION IS IN THE HIGHER NIBBLE */
2963         oct >>= 4;
2964
2965         switch ( oct&7 )
2966         {
2967                 case 1: str="priority level 1 (highest)"; break;
2968                 case 2: str="priority level 2"; break;
2969                 case 3: str="priority level 3"; break;
2970                 case 4: str="priority level 4 (lowest)"; break;
2971                 default: str="priority level 4 (lowest)";
2972         }
2973
2974         proto_tree_add_text(tree,
2975                 tvb, curr_offset, 1,
2976                 "Radio Priority (TOM8): (%u) %s",
2977                 oct&7,
2978                 str);
2979
2980         curr_offset++;
2981
2982         return(curr_offset - offset);
2983 }
2984
2985 /*
2986  * [8] 10.5.7.6 MBMS context status
2987  */
2988 static guint16
2989 de_gc_mbms_context_stat(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2990 {
2991         guint32 curr_offset;
2992         guint8  oct, i, j;
2993         proto_item  *tf = NULL;
2994         proto_tree  *tf_tree = NULL;
2995
2996         curr_offset = offset;
2997
2998         oct = tvb_get_guint8(tvb, curr_offset);
2999
3000         tf = proto_tree_add_text(tree,
3001                 tvb, curr_offset, 1,
3002                 "MBMS Context Status");
3003
3004         tf_tree = proto_item_add_subtree(tf, ett_gmm_context_stat );
3005
3006         for (i=0; i<len; i++)
3007         {
3008                 oct = tvb_get_guint8(tvb, curr_offset);
3009
3010                 for (j=0; j<8; j++)
3011                 {
3012                         proto_tree_add_text(tf_tree,
3013                                 tvb, curr_offset, 1,
3014                                 "NSAPI %d: (%u) %s",128+i*8+j,
3015                                 oct&1,
3016                                 pdp_str[oct&1]);
3017                         oct>>=1;
3018                 }
3019                 curr_offset++;
3020         }
3021
3022         return(len);
3023 }
3024 /*
3025  * [7] 10.5.6.1
3026  */
3027 #define MAX_APN_LENGTH          50
3028
3029 guint16
3030 de_sm_apn(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len _U_)
3031 {
3032         guint32 curr_offset;
3033         guint   curr_len;
3034         const guint8    *cptr;
3035         guint8    str[MAX_APN_LENGTH+1];
3036
3037         cptr = tvb_get_ptr(tvb, offset, len);
3038
3039         curr_offset = offset;
3040
3041         /* init buffer and copy it */
3042         memset ( str , 0 , MAX_APN_LENGTH );
3043         memcpy ( str , cptr , len<MAX_APN_LENGTH?len:MAX_APN_LENGTH );
3044
3045         curr_len = 0;
3046         while (( curr_len < len ) && ( curr_len < MAX_APN_LENGTH ))
3047         {
3048                 guint step = str[curr_len];
3049                 str[curr_len]='.';
3050                 curr_len += step+1;
3051         }
3052
3053         proto_tree_add_text(tree,
3054                 tvb, curr_offset, len,
3055                 "APN: %s %s", str+1 , add_string ? add_string : "");
3056
3057         curr_offset+= len;
3058
3059         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3060
3061         return(curr_offset - offset);
3062 }
3063
3064 /*
3065  * [7] 10.5.6.2
3066  */
3067 static guint16
3068 de_sm_nsapi(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len _U_)
3069 {
3070         guint8  oct;
3071         guint32 curr_offset;
3072
3073         curr_offset = offset;
3074
3075         oct = tvb_get_guint8(tvb, curr_offset);
3076
3077         proto_tree_add_text(tree,
3078                 tvb, curr_offset, 1,
3079                 "NSAPI: 0x%02x (%u) %s",
3080                 oct&0x0f, oct&0x0f,add_string ? add_string : "");
3081
3082         curr_offset++;
3083
3084         return(curr_offset - offset);
3085 }
3086
3087 /*
3088  * [7] 10.5.6.3 Protocol configuration options
3089  */
3090 #if 0
3091 static const value_string gsm_a_sm_pco_ms2net_prot_vals[] = {
3092         { 0x01, "P-CSCF Address Request" },
3093         { 0x02, "IM CN Subsystem Signaling Flag" },
3094         { 0x03, "DNS Server Address Request" },
3095         { 0x04, "Not Supported" },
3096         { 0x05, "MS Support of Network Requested Bearer Control indicator" },
3097         { 0x06, "Reserved" },
3098         { 0x07, "DSMIPv6 Home Agent Address Request" },
3099         { 0x08, "DSMIPv6 Home Network Prefix Request" },
3100         { 0x09, "DSMIPv6 IPv4 Home Agent Address Request" },
3101         { 0x0a, "IP address allocation via NAS signalling" },
3102         { 0x0b, "IPv4 address allocation via DHCPv4" },
3103         { 0, NULL }
3104 };
3105 static const value_string gsm_a_sm_pco_net2ms_prot_vals[] = {
3106         { 0x01, "P-CSCF Address" },
3107         { 0x02, "IM CN Subsystem Signaling Flag" },
3108         { 0x03, "DNS Server Address" },
3109         { 0x04, "Policy Control rejection code" },
3110         { 0x05, "Selected Bearer Control Mode" },
3111         { 0x06, "Reserved" },
3112         { 0x07, "DSMIPv6 Home Agent Address" },
3113         { 0x08, "DSMIPv6 Home Network Prefix" },
3114         { 0x09, "DSMIPv6 IPv4 Home Agent Address" },
3115         { 0, NULL }
3116 };
3117 #endif
3118 guint16
3119 de_sm_pco(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3120 {
3121         guint32 curr_offset;
3122         guint   curr_len;
3123         guchar  oct;
3124         struct e_in6_addr ipv6_addr;
3125
3126         curr_len = len;
3127         curr_offset = offset;
3128
3129         oct = tvb_get_guint8(tvb, curr_offset);
3130
3131         proto_tree_add_item(tree, hf_gsm_a_gm_sm_ext, tvb, curr_offset, 1, FALSE);
3132         proto_tree_add_text(tree,tvb, curr_offset, 1, "Configuration Protocol: PPP (%u)",oct&0x0f);
3133         curr_len--;
3134         curr_offset++;
3135
3136         while ( curr_len > 0 )
3137         {
3138                 guchar e_len;
3139                 guint16 prot;
3140                 tvbuff_t *l3_tvb;
3141                 dissector_handle_t handle = NULL;
3142
3143                 prot = tvb_get_ntohs(tvb,curr_offset);
3144                 e_len = tvb_get_guint8(tvb, curr_offset+2);
3145                 curr_len-=3;
3146                 curr_offset+=3;
3147
3148                 switch ( prot )
3149                 {
3150                         case 0x0001:
3151                         {
3152                                 if (e_len == 0) {
3153                                         proto_tree_add_text(tree,tvb, curr_offset-3, 2, "Parameter: (%u) P-CSCF Address Request" , prot );
3154                                 } else {
3155                                         proto_tree_add_text(tree,tvb, curr_offset-3, 2, "Parameter: (%u) P-CSCF Address" , prot );
3156                                 }
3157                                 proto_tree_add_text(tree,tvb, curr_offset-1, 1, "Length: 0x%02x (%u)", e_len , e_len);
3158
3159                                 if (e_len > 0) {
3160                                         tvb_get_ipv6(tvb, curr_offset, &ipv6_addr);
3161                                         proto_tree_add_text(tree,
3162                                         tvb, curr_offset, 16,
3163                                         "IPv6: %s", ip6_to_str(&ipv6_addr));
3164                                 }
3165                                 break;
3166                         }
3167                         case 0x0002:
3168                                 proto_tree_add_text(tree,tvb, curr_offset-3, 2, "Parameter: (%u) IM CN Subsystem Signaling Flag" , prot );
3169                                 proto_tree_add_text(tree,tvb, curr_offset-1, 1, "Length: 0x%02x (%u)", e_len , e_len);
3170                                 break;
3171                         case 0x0003:
3172                         {
3173                                 if (e_len == 0) {
3174                                         proto_tree_add_text(tree,tvb, curr_offset-3, 2, "Parameter: (%u) DNS Server Address Request" , prot );
3175                                 } else {
3176                                         proto_tree_add_text(tree,tvb, curr_offset-3, 2, "Parameter: (%u) DNS Server Address" , prot );
3177                                 }
3178                                 proto_tree_add_text(tree,tvb, curr_offset-1, 1, "Length: 0x%02x (%u)", e_len , e_len);
3179
3180                                 if (e_len > 0) {
3181                                         tvb_get_ipv6(tvb, curr_offset, &ipv6_addr);
3182                                         proto_tree_add_text(tree,
3183                                         tvb, curr_offset, 16,
3184                                         "IPv6: %s", ip6_to_str(&ipv6_addr));
3185                                 }
3186                                 break;
3187                         }
3188                         case 0x0004:
3189                                 proto_tree_add_text(tree,tvb, curr_offset-3, 2, "Parameter: (%u) Policy Control rejection code" , prot );
3190                                 proto_tree_add_text(tree,tvb, curr_offset-1, 1, "Length: 0x%02x (%u)", e_len , e_len);
3191                                 oct = tvb_get_guint8(tvb, curr_offset);
3192                                 proto_tree_add_text(tree,tvb, curr_offset, 1, "Reject Code: 0x%02x (%u)", e_len , e_len);
3193                                 break;
3194                         default:
3195                         {
3196                                 handle = dissector_get_port_handle ( gprs_sm_pco_subdissector_table , prot );
3197                                 if ( handle != NULL )
3198                                 {
3199                                         proto_tree_add_text(tree,tvb, curr_offset-3, 2, "Protocol: (%u) %s" ,
3200                                         prot , val_to_str(prot, ppp_vals, "Unknown"));
3201                                         proto_tree_add_text(tree,tvb, curr_offset-1, 1, "Length: 0x%02x (%u)", e_len , e_len);
3202                                         /*
3203                                          * dissect the embedded message
3204                                          */
3205                                         l3_tvb = tvb_new_subset(tvb, curr_offset, e_len, e_len);
3206                                         call_dissector(handle, l3_tvb ,  gsm_a_dtap_pinfo  , tree );
3207                                 }
3208                                 else
3209                                 {
3210                                         proto_tree_add_text(tree,tvb, curr_offset-3, 2, "Protocol/Parameter: (%u) unknown" , prot );
3211                                         proto_tree_add_text(tree,tvb, curr_offset-1, 1, "Length: 0x%02x (%u)", e_len , e_len);
3212                                         /*
3213                                         * dissect the embedded DATA message
3214                                         */
3215                                         l3_tvb = tvb_new_subset(tvb, curr_offset, e_len, e_len);
3216                                         call_dissector(data_handle, l3_tvb, gsm_a_dtap_pinfo , tree);
3217                                 }
3218                         }
3219                 }
3220
3221                 curr_len-= e_len;
3222                 curr_offset+= e_len;
3223         }
3224         curr_offset+= curr_len;
3225
3226         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3227
3228         return(curr_offset - offset);
3229 }
3230
3231 /*
3232  * [7] 10.5.6.4
3233  */
3234 static guint16
3235 de_sm_pdp_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3236 {
3237         guint32 curr_offset;
3238         guint   curr_len;
3239         const gchar     *str;
3240         guchar    oct;
3241         guchar    oct2;
3242         struct e_in6_addr ipv6_addr;
3243
3244         curr_len = len;
3245         curr_offset = offset;
3246
3247         oct = tvb_get_guint8(tvb, curr_offset);
3248
3249         switch ( oct&0x0f )
3250         {
3251                 case 0x00: str="ETSI allocated address"; break;
3252                 case 0x01: str="IETF allocated address"; break;
3253                 case 0x0f: str="Empty PDP type"; break;
3254                 default: str="reserved";
3255         }
3256
3257         proto_tree_add_text(tree,
3258                 tvb, curr_offset, 1,
3259                 "PDP type organisation: (%u) %s",oct&0x0f,str);
3260
3261         oct2 = tvb_get_guint8(tvb, curr_offset+1);
3262
3263         if (( oct&0x0f ) == 0 )
3264         {
3265                 switch ( oct2 )
3266                 {
3267                         case 0x00: str="Reserved, used in earlier version of this protocol"; break;
3268                         case 0x01: str="PDP-type PPP"; break;
3269                         default: str="reserved";
3270                 }
3271         }
3272         else if (( oct&0x0f) == 1 )
3273         {
3274                 switch ( oct2 )
3275                 {
3276                         case 0x21: str="IPv4 address"; break;
3277                         case 0x57: str="IPv6 address"; break;
3278                         default: str="IPv4 address";
3279                 }
3280         }
3281         else if ((oct2==0) && (( oct&0x0f) == 0x0f ))
3282                 str="Empty";
3283         else
3284                 str="Not specified";    
3285
3286         proto_tree_add_text(tree,
3287                 tvb, curr_offset+1, 1,
3288                 "PDP type number: (%u) %s",oct2,str);
3289
3290         if (( len == 2 ) && (( oct2 == 0x21 ) || ( oct2 == 0x57 )))
3291         {
3292                 proto_tree_add_text(tree,
3293                         tvb, curr_offset+1, 1,
3294                         "Dynamic addressing");
3295
3296                 curr_offset+= curr_len;
3297
3298                 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3299
3300                 return(curr_offset - offset);
3301         }
3302         else if ( len == 2 )
3303         {
3304                 proto_tree_add_text(tree,
3305                         tvb, curr_offset+1, 1,
3306                         "No PDP address is included");
3307
3308                 curr_offset+= curr_len;
3309
3310                 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3311
3312                 return(curr_offset - offset);
3313         }
3314         else if ( len < 2 )
3315         {
3316                 proto_tree_add_text(tree,
3317                         tvb, curr_offset+1, 1,
3318                         "Length is bogus - should be >= 2");
3319
3320                 curr_offset+= curr_len;
3321
3322                 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3323
3324                 return(curr_offset - offset);
3325         }
3326
3327         if ((( oct2 == 0x21 ) && ( len != 6 )) ||
3328            (( oct2 == 0x57 ) && ( len != 18 )))
3329         {
3330                 proto_tree_add_text(tree,
3331                         tvb, curr_offset+2, len-2,
3332                         "Can't display address");
3333         }
3334
3335         switch ( oct2 )
3336         {
3337                 case 0x21:
3338                         if (len-2 != 4) {
3339                                 proto_tree_add_text(tree,
3340                                 tvb, curr_offset+2, 0,
3341                                         "IPv4: length is wrong");
3342                         } else {
3343                                 proto_tree_add_text(tree,
3344                                         tvb, curr_offset+2, len-2,
3345                                         "IPv4: %s", ip_to_str(tvb_get_ptr(tvb, offset+2, 4)));
3346                         }
3347                         break;
3348
3349                 case 0x57:
3350                         if (len-2 != 16) {
3351                                 proto_tree_add_text(tree,
3352                                         tvb, curr_offset+2, 0,
3353                                         "IPv6: length is wrong");
3354                         } else {
3355                                 tvb_get_ipv6(tvb, curr_offset+2, &ipv6_addr);
3356                                 proto_tree_add_text(tree,
3357                                         tvb, curr_offset+2, len-2,
3358                                         "IPv6: %s", ip6_to_str(&ipv6_addr));
3359                         }
3360                         break;
3361         }
3362
3363         curr_offset+= curr_len;
3364         
3365         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3366
3367         return(curr_offset - offset);
3368 }
3369
3370 /*
3371  * [7] 10.5.6.5 3GPP TS 24.008 version 7.8.0 Release 7
3372  */
3373
3374 static const value_string gsm_a_qos_delay_cls_vals[] = {
3375         { 0x00, "Subscribed delay class (in MS to network direction)" },
3376         { 0x01, "Delay class 1" },
3377         { 0x02, "Delay class 2" },
3378         { 0x03, "Delay class 3" },
3379         { 0x04, "Delay class 4 (best effort)" },
3380         { 0x07, "Reserved" },
3381         { 0, NULL }
3382 };
3383
3384 static const value_string gsm_a_qos_reliability_vals[] = {
3385         { 0x00, "Subscribed reliability class (in MS to network direction)" },
3386         { 0x01, "Acknowledged GTP, LLC, and RLC; Protected data" },
3387         { 0x02, "Unacknowledged GTP, Ack LLC/RLC, Protected data" },
3388         { 0x03, "Unacknowledged GTP/LLC, Ack RLC, Protected data" },
3389         { 0x04, "Unacknowledged GTP/LLC/RLC, Protected data" },
3390         { 0x05, "Unacknowledged GTP/LLC/RLC, Unprotected data" },
3391         { 0x07, "Reserved" },
3392         { 0, NULL }
3393 };
3394  /* Delivery of erroneous SDUs, octet 6 (see 3GPP TS 23.107) Bits 3 2 1 */
3395 const value_string gsm_a_qos_del_of_err_sdu_vals[] = {
3396         { 0, "Subscribed delivery of erroneous SDUs/Reserved" },
3397         { 1, "No detect('-')" },
3398         { 2, "Erroneous SDUs are delivered('yes')" },
3399         { 3, "Erroneous SDUs are not delivered('No')" },
3400         { 7, "Reserved" },
3401         { 0, NULL }
3402 };
3403
3404  /* Delivery order, octet 6 (see 3GPP TS 23.107) Bits 5 4 3 */
3405 const value_string gsm_a_qos_del_order_vals[] = {
3406         { 0, "Subscribed delivery order/Reserved" },
3407         { 1, "With delivery order ('yes')" },
3408         { 2, "Without delivery order ('no')" },
3409         { 3, "Reserved" },
3410         { 0, NULL }
3411 };
3412 /* Traffic class, octet 6 (see 3GPP TS 23.107) Bits 8 7 6 */
3413 const value_string gsm_a_qos_traffic_cls_vals[] = {
3414         { 0, "Subscribed traffic class/Reserved" },
3415         { 1, "Conversational class" },
3416         { 2, "Streaming class" },
3417         { 3, "Interactive class" },
3418         { 4, "Background class" },
3419         { 7, "Reserved" },
3420         { 0, NULL }
3421 };
3422
3423 /* Residual Bit Error Rate (BER), octet 10 (see 3GPP TS 23.107) Bits 8 7 6 5 */
3424 const value_string gsm_a_qos_ber_vals[] = {
3425         { 0, "Subscribed residual BER/Reserved" },
3426         { 1, "5*10-2" },
3427         { 2, "1*10-2" },
3428         { 3, "5*10-3" },
3429         { 4, "4*10-3" },
3430         { 5, "1*10-3" },
3431         { 6, "1*10-4" },
3432         { 7, "1*10-5" },
3433         { 8, "1*10-6" },
3434         { 9, "6*10-8" },
3435         { 10, "Reserved" },
3436         { 0, NULL }
3437 };
3438
3439 /* SDU error ratio, octet 10 (see 3GPP TS 23.107) Bits 4 3 2 1 */
3440 const value_string gsm_a_qos_sdu_err_rat_vals[] = {
3441         { 0, "Subscribed SDU error ratio/Reserved" },
3442         { 1, "1*10-2" },
3443         { 2, "7*10-3" },
3444         { 3, "1*10-3" },
3445         { 4, "1*10-4" },
3446         { 5, "1*10-5" },
3447         { 6, "1*10-6" },
3448         { 7, "1*10-1" },
3449         { 15, "Reserved" },
3450         { 0, NULL }
3451 };
3452
3453 /* Traffic handling priority, octet 11 (see 3GPP TS 23.107) Bits 2 1 */
3454 const value_string gsm_a_qos_traff_hdl_pri_vals[] = {
3455         { 0, "Subscribed traffic handling priority/Reserved" },
3456         { 1, "Priority level 1" },
3457         { 2, "Priority level 2" },
3458         { 3, "Priority level 3" },
3459         { 0, NULL }
3460 };
3461
3462 guint16
3463 de_sm_qos(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3464 {
3465         guint32 curr_offset;
3466         guint   curr_len;
3467         guchar     oct, tmp_oct;
3468         const gchar     *str;
3469
3470         curr_len = len;
3471         curr_offset = offset;
3472
3473         oct = tvb_get_guint8(tvb, curr_offset);
3474
3475         proto_tree_add_item(tree, hf_gsm_a_qos_delay_cls, tvb, curr_offset, 1, FALSE);
3476         proto_tree_add_item(tree, hf_gsm_a_qos_qos_reliability_cls, tvb, curr_offset, 1, FALSE);
3477
3478         curr_offset+= 1;
3479         curr_len-= 1;
3480
3481         if ( curr_len == 0 )
3482         {
3483                 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3484
3485                 return(curr_offset - offset);
3486         }
3487
3488         oct = tvb_get_guint8(tvb, curr_offset);
3489
3490         switch ( oct>>4 )
3491         {
3492                 case 0x00: str="Subscribed peak throughput/reserved"; break;
3493                 case 0x01: str="Up to 1 000 octet/s"; break;
3494                 case 0x02: str="Up to 2 000 octet/s"; break;
3495                 case 0x03: str="Up to 4 000 octet/s"; break;
3496                 case 0x04: str="Up to 8 000 octet/s"; break;
3497                 case 0x05: str="Up to 16 000 octet/s"; break;
3498                 case 0x06: str="Up to 32 000 octet/s"; break;
3499                 case 0x07: str="Up to 64 000 octet/s"; break;
3500                 case 0x08: str="Up to 128 000 octet/s"; break;
3501                 case 0x09: str="Up to 256 000 octet/s"; break;
3502                 case 0x0f: str="Reserved"; break;
3503                 default: str="Up to 1 000 octet/s";
3504         }
3505
3506         proto_tree_add_text(tree,
3507                 tvb, curr_offset, 1,
3508                 "Peak throughput: (%u) %s",oct>>4,str);
3509
3510         switch ( oct&0x7 )
3511         {
3512                 case 0x00: str="Subscribed precedence/reserved"; break;
3513                 case 0x01: str="High priority"; break;
3514                 case 0x02: str="Normal priority"; break;
3515                 case 0x03: str="Low priority"; break;
3516                 case 0x07: str="Reserved"; break;
3517                 default: str="Normal priority";
3518         }
3519
3520         proto_tree_add_text(tree,
3521                 tvb, curr_offset, 1,
3522                 "Precedence class: (%u) %s",oct&7,str);
3523
3524         curr_offset+= 1;
3525         curr_len-= 1;
3526
3527         if ( curr_len == 0 )
3528         {
3529                 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3530
3531                 return(curr_offset - offset);
3532         }
3533
3534         oct = tvb_get_guint8(tvb, curr_offset);
3535
3536         switch ( oct&0x1f )
3537         {
3538                 case 0x00: str="Subscribed peak throughput/reserved"; break;
3539                 case 0x01: str="100 octet/h"; break;
3540                 case 0x02: str="200 octet/h"; break;
3541                 case 0x03: str="500 octet/h"; break;
3542                 case 0x04: str="1 000 octet/h"; break;
3543                 case 0x05: str="2 000 octet/h"; break;
3544                 case 0x06: str="5 000 octet/h"; break;
3545                 case 0x07: str="10 000 octet/h"; break;
3546                 case 0x08: str="20 000 octet/h"; break;
3547                 case 0x09: str="50 000 octet/h"; break;
3548                 case 0x0a: str="100 000 octet/h"; break;
3549                 case 0x0b: str="200 000 octet/h"; break;
3550                 case 0x0c: str="500 000 octet/h"; break;
3551                 case 0x0d: str="1 000 000 octet/h"; break;
3552                 case 0x0e: str="2 000 000 octet/h"; break;
3553                 case 0x0f: str="5 000 000 octet/h"; break;
3554                 case 0x10: str="10 000 000 octet/h"; break;
3555                 case 0x11: str="20 000 000 octet/h"; break;
3556                 case 0x12: str="50 000 000 octet/h"; break;
3557                 case 0x1e: str="Reserved"; break;
3558                 case 0x1f: str="Best effort"; break;
3559                 default: str="Best effort";
3560         }
3561
3562         proto_tree_add_text(tree,
3563                 tvb, curr_offset, 1,
3564                 "Mean throughput: (%u) %s",oct&0x1f,str);
3565
3566         curr_offset+= 1;
3567         curr_len-= 1;
3568
3569         if ( curr_len == 0 )
3570         {
3571                 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3572
3573                 return(curr_offset - offset);
3574         }
3575
3576         proto_tree_add_item(tree, hf_gsm_a_qos_traffic_cls, tvb, curr_offset, 1, FALSE);
3577         proto_tree_add_item(tree, hf_gsm_a_qos_del_order, tvb, curr_offset, 1, FALSE);
3578         proto_tree_add_item(tree, hf_gsm_a_qos_del_of_err_sdu, tvb, curr_offset, 1, FALSE);
3579
3580         curr_offset+= 1;
3581         curr_len-= 1;
3582
3583         if ( curr_len == 0 )
3584         {
3585                 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3586
3587                 return(curr_offset - offset);
3588         }
3589
3590         oct = tvb_get_guint8(tvb, curr_offset);
3591
3592         switch ( oct )
3593         {
3594                 case 0x00: str="Subscribed maximum SDU size/reserved"; break;
3595                 case 0x97: str="1502 octets"; break;
3596                 case 0x98: str="1510 octets"; break;
3597                 case 0x99: str="1520 octets"; break;
3598                 case 0xff: str="Reserved"; break;
3599                 default: str="Unspecified";
3600         }
3601
3602         if (( oct >= 1 ) && ( oct <= 0x96 ))
3603                 proto_tree_add_text(tree,
3604                         tvb, curr_offset, 1,
3605                         "Maximum SDU size: (%u) %u octets",oct,oct*10);
3606         else
3607                 proto_tree_add_text(tree,
3608                         tvb, curr_offset, 1,
3609                         "Maximum SDU size: (%u) %s",oct,str);
3610
3611         curr_offset+= 1;
3612         curr_len-= 1;
3613
3614         if ( curr_len == 0 )
3615         {
3616                 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3617
3618                 return(curr_offset - offset);
3619         }
3620
3621         oct = tvb_get_guint8(tvb, curr_offset);
3622
3623         switch ( oct )
3624         {
3625                 case 0x00: str="Subscribed maximum bit rate for uplink/reserved"; break;
3626                 case 0xff: str="0kbps"; break;
3627                 default: str="This should not happen - BUG";
3628         }
3629
3630         if (( oct >= 1 ) && ( oct <= 0x3f ))
3631                 proto_tree_add_text(tree,
3632                         tvb, curr_offset, 1,
3633                         "Maximum bit rate for uplink: (%u) %ukbps",oct,oct);
3634         else if (( oct >= 0x40 ) && ( oct <= 0x7f ))
3635                 proto_tree_add_text(tree,
3636                         tvb, curr_offset, 1,
3637                         "Maximum bit rate for uplink: (%u) %ukbps",oct,(oct-0x40)*8+64); /* - was (oct-0x40)*8  */
3638         else if (( oct >= 0x80 ) && ( oct <= 0xfe ))
3639                 proto_tree_add_text(tree,
3640                         tvb, curr_offset, 1,
3641                         "Maximum bit rate for uplink: (%u) %ukbps",oct,(oct-0x80)*64+576); /* - was (oct-0x80)*64 */
3642         else
3643                 proto_tree_add_text(tree,
3644                         tvb, curr_offset, 1,
3645                         "Maximum bit rate for uplink: (%u) %s",oct,str);
3646
3647         curr_offset+= 1;
3648         curr_len-= 1;
3649
3650         if ( curr_len == 0 )
3651         {
3652                 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3653
3654                 return(curr_offset - offset);
3655         }
3656
3657         oct = tvb_get_guint8(tvb, curr_offset);
3658
3659         switch ( oct )
3660         {
3661                 case 0x00: str="Subscribed maximum bit rate for uplink/reserved"; break;
3662                 case 0xff: str="0kbps"; break;
3663                 default: str="This should not happen - BUG";
3664         }
3665
3666         if (( oct >= 1 ) && ( oct <= 0x3f ))
3667                 proto_tree_add_text(tree,
3668                         tvb, curr_offset, 1,
3669                 "Maximum bit rate for downlink: (%u) %ukbps",oct,oct);
3670         else if (( oct >= 0x40 ) && ( oct <= 0x7f ))
3671                 proto_tree_add_text(tree,
3672                         tvb, curr_offset, 1,
3673                         "Maximum bit rate for downlink: (%u) %ukbps",oct,(oct-0x40)*8+64);/*same as above*/
3674         else if (( oct >= 0x80 ) && ( oct <= 0xfe ))
3675                 proto_tree_add_text(tree,
3676                         tvb, curr_offset, 1,
3677                         "Maximum bit rate for downlink: (%u) %ukbps",oct,(oct-0x80)*64+576);/*same as above*/
3678         else
3679                 proto_tree_add_text(tree,
3680                         tvb, curr_offset, 1,
3681                         "Maximum bit rate for downlink: (%u) %s",oct,str);
3682
3683         curr_offset+= 1;
3684         curr_len-= 1;
3685
3686         if ( curr_len == 0 )
3687         {
3688                 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3689
3690                 return(curr_offset - offset);
3691         }
3692
3693         /* Octet 10 */
3694         proto_tree_add_item(tree, hf_gsm_a_qos_ber, tvb, curr_offset, 1, FALSE);
3695         proto_tree_add_item(tree, hf_gsm_a_qos_sdu_err_rat, tvb, curr_offset, 1, FALSE);
3696
3697         curr_offset+= 1;
3698         curr_len-= 1;
3699
3700         if ( curr_len == 0 )
3701         {
3702                 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3703
3704                 return(curr_offset - offset);
3705         }
3706
3707         /* Octet 11 */
3708         oct = tvb_get_guint8(tvb, curr_offset);
3709
3710         switch ( oct>>2 )
3711         {
3712                 case 0x00: str="Subscribed transfer delay/reserved"; break;
3713                 case 0x3f: str="Reserved"; break;
3714                 default: str="This should not happen - BUG";
3715         }
3716
3717         tmp_oct = oct>>2;
3718
3719         if (( tmp_oct >= 1 ) && ( tmp_oct <= 0x0f ))
3720                 proto_tree_add_text(tree,
3721                         tvb, curr_offset, 1,
3722                         "Transfer Delay: (%u) %ums",oct>>2,(oct>>2)*10);
3723         else if (( tmp_oct >= 0x10 ) && ( tmp_oct <= 0x1f ))
3724                 proto_tree_add_text(tree,
3725                         tvb, curr_offset, 1,
3726                         "Transfer Delay: (%u) %ums",oct>>2,((oct>>2)-0x10)*50+200);
3727         else if (( tmp_oct >= 0x20 ) && ( tmp_oct <= 0x3e ))
3728                 proto_tree_add_text(tree,
3729                         tvb, curr_offset, 1,
3730                         "Transfer Delay: (%u) %ums",oct>>2,((oct>>2)-0x20)*100+1000);
3731         else
3732                 proto_tree_add_text(tree,
3733                         tvb, curr_offset, 1,
3734                         "Transfer Delay: (%u) %s",oct>>2,str);
3735
3736         switch ( oct&0x03 )
3737         {
3738                 case 0x00: str="Subscribed traffic handling priority/reserved"; break;
3739                 case 0x01: str="Priority level 1"; break;
3740                 case 0x02: str="Priority level 2"; break;
3741                 case 0x03: str="Priority level 3"; break;
3742                 default: str="This should not happen - BUG";
3743         }
3744
3745         proto_tree_add_text(tree,
3746                 tvb, curr_offset, 1,
3747                 "Traffic Handling priority: (%u) %s",oct&0x03,str);
3748
3749         curr_offset+= 1;
3750         curr_len-= 1;
3751
3752         if ( curr_len == 0 )
3753         {
3754                 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3755
3756                 return(curr_offset - offset);
3757         }
3758
3759         /* Octet 12 */
3760         oct = tvb_get_guint8(tvb, curr_offset);
3761
3762         switch ( oct )
3763         {
3764                 case 0x00: str="Subscribed guaranteed bit rate for uplink/reserved"; break;
3765                 case 0xff: str="0kbps"; break;
3766                 default: str="This should not happen - BUG";
3767         }
3768
3769         if (( oct >= 1 ) && ( oct <= 0x3f ))
3770                 proto_tree_add_text(tree,
3771                         tvb, curr_offset, 1,
3772                         "Guaranteed bit rate for uplink: (%u) %ukbps",oct,oct);
3773         else if (( oct >= 0x40 ) && ( oct <= 0x7f ))
3774                 proto_tree_add_text(tree,
3775                         tvb, curr_offset, 1,
3776                         "Guaranteed bit rate for uplink: (%u) %ukbps",oct,(oct-0x40)*8+64);/*same as for max bit rate*/
3777         else if (( oct >= 0x80 ) && ( oct <= 0xfe ))
3778                 proto_tree_add_text(tree,
3779                         tvb, curr_offset, 1,
3780                         "Guaranteed bit rate for uplink: (%u) %ukbps",oct,(oct-0x80)*64+576);/*same as for max bit rate*/
3781         else
3782                 proto_tree_add_text(tree,
3783                         tvb, curr_offset, 1,
3784                         "Guaranteed bit rate for uplink: (%u) %s",oct,str);
3785
3786         curr_offset+= 1;
3787         curr_len-= 1;
3788
3789         if ( curr_len == 0 )
3790         {
3791                 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3792
3793                 return(curr_offset - offset);
3794         }
3795
3796         oct = tvb_get_guint8(tvb, curr_offset);
3797
3798         switch ( oct )
3799         {
3800                 case 0x00: str="Subscribed guaranteed bit rate for uplink/reserved"; break;
3801                 case 0xff: str="0kbps"; break;
3802                 default: str="This should not happen - BUG";
3803         }
3804
3805         if (( oct >= 1 ) && ( oct <= 0x3f ))
3806                 proto_tree_add_text(tree,
3807                         tvb, curr_offset, 1,
3808                         "Guaranteed bit rate for downlink: (%u) %ukbps",oct,oct);
3809         else if (( oct >= 0x40 ) && ( oct <= 0x7f ))
3810                 proto_tree_add_text(tree,
3811                         tvb, curr_offset, 1,
3812                         "Guaranteed bit rate for downlink: (%u) %ukbps",oct,(oct-0x40)*8+64);/*same as above*/
3813         else if (( oct >= 0x80 ) && ( oct <= 0xfe ))
3814                 proto_tree_add_text(tree,
3815                         tvb, curr_offset, 1,
3816                         "Guaranteed bit rate for downlink: (%u) %ukbps",oct,(oct-0x80)*64+576);/*same as above*/
3817         else
3818                 proto_tree_add_text(tree,
3819                         tvb, curr_offset, 1,
3820                         "Guaranteed bit rate for downlink: (%u) %s",oct,str);
3821
3822         curr_offset+= 1;
3823         curr_len-= 1;
3824
3825         if ( curr_len == 0 )
3826         {
3827                 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3828
3829                 return(curr_offset - offset);
3830         }
3831
3832         /* Ocet 14 */
3833         oct = tvb_get_guint8(tvb, curr_offset);
3834
3835         switch ( (oct>>4)&1 )
3836         {
3837                 case 0x00: str="Not optimised for signalling traffic"; break;
3838                 case 0x01: str="Optimised for signalling traffic"; break;
3839                 default: str="This should not happen - BUG";
3840         }
3841
3842         proto_tree_add_text(tree,
3843                 tvb, curr_offset, 1,
3844                 "Signalling Indication: (%u) %s",(oct>>4)&1,str);
3845
3846         switch ( oct&7 )
3847         {
3848                 case 0x00: str="unknown"; break;
3849                 case 0x01: str="speech"; break;
3850                 default: str="unknown";
3851         }
3852
3853         proto_tree_add_text(tree,
3854                 tvb, curr_offset, 1,
3855                 "Source Statistics Descriptor: (%u) %s",oct&7,str);
3856
3857         curr_offset+= 1;
3858         curr_len-= 1;
3859
3860         if ( curr_len == 0 )
3861         {
3862                 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3863
3864                 return(curr_offset - offset);
3865         }
3866
3867         /* Octet 15 */
3868
3869         oct = tvb_get_guint8(tvb, curr_offset);
3870
3871         switch ( oct )
3872         {
3873                 case 0x00: str="Use the value indicated by the Maximum bit rate for downlink"; break;
3874                 default: str="Unspecified";
3875         }
3876
3877         if (( oct >= 1 ) && ( oct <= 0x4a ))
3878                 proto_tree_add_text(tree,
3879                         tvb, curr_offset, 1,
3880                         "Maximum bit rate for downlink (extended): (%u) %ukbps",oct,oct*100);
3881         if (( oct >= 0x4b ) && ( oct <= 0xba ))
3882                 proto_tree_add_text(tree,
3883                         tvb, curr_offset, 1,
3884                         "Maximum bit rate for downlink (extended): (%u) %uMbps",oct,16 + oct- 0x4a);
3885         if (( oct >= 0xbb ) && ( oct <= 0xfa ))
3886                 proto_tree_add_text(tree,
3887                         tvb, curr_offset, 1,
3888                         "Maximum bit rate for downlink (extended): (%u) %uMbps",oct,128 + oct - 0xba * 2);
3889         else
3890                 proto_tree_add_text(tree,
3891                         tvb, curr_offset, 1,
3892                         "Maximum bit rate for downlink (extended): (%u) %s",oct,str);
3893
3894         curr_offset+= 1;
3895         curr_len-= 1;
3896
3897         if ( curr_len == 0 )
3898         {
3899                 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3900
3901                 return(curr_offset - offset);
3902         }
3903
3904         /* Octet 16 */
3905         oct = tvb_get_guint8(tvb, curr_offset);
3906
3907         switch ( oct )
3908         {
3909                 case 0x00: str="Use the value indicated by the Guaranteed bit rate for downlink"; break;
3910                 default: str="Unspecified";
3911         }
3912
3913         if (( oct >= 1 ) && ( oct <= 0x4a ))
3914                 proto_tree_add_text(tree,
3915                         tvb, curr_offset, 1,
3916                         "Guaranteed bit rate for downlink (extended): (%u) %ukbps",oct,oct*100);
3917         if (( oct >= 0x4b ) && ( oct <= 0xba ))
3918                 proto_tree_add_text(tree,
3919                         tvb, curr_offset, 1,
3920                         "Guaranteed bit rate for downlink (extended): (%u) %uMbps",oct,16 + oct- 0x4a);
3921         if (( oct >= 0xbb ) && ( oct <= 0xfa ))
3922                 proto_tree_add_text(tree,
3923                         tvb, curr_offset, 1,
3924                         "Guaranteed bit rate for downlink (extended): (%u) %uMbps",oct,128 + oct - 0xba * 2);
3925         else
3926                 proto_tree_add_text(tree,
3927                         tvb, curr_offset, 1,
3928                         "Guaranteed bit rate for downlink (extended): (%u) %s",oct,str);
3929
3930         curr_offset+= 1;
3931         curr_len-= 1;
3932
3933         if ( curr_len == 0 )
3934         {
3935                 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3936
3937                 return(curr_offset - offset);
3938         }
3939         /* Maximum bit rate for uplink (extended) Octet 17 */
3940         oct = tvb_get_guint8(tvb, curr_offset);
3941
3942         switch ( oct )
3943         {
3944                 case 0x00: str="Use the value indicated by the Maximum bit rate for uplink"; break;
3945                 default: str="Unspecified";
3946         }
3947
3948         if (( oct >= 1 ) && ( oct <= 0x4a ))
3949                 proto_tree_add_text(tree,
3950                         tvb, curr_offset, 1,
3951                         "Maximum bit rate for uplink (extended): (%u) %ukbps",oct,oct*100);
3952         if (( oct >= 0x4b ) && ( oct <= 0xba ))
3953                 proto_tree_add_text(tree,
3954                         tvb, curr_offset, 1,
3955                         "Maximum bit rate for uplink (extended): (%u) %uMbps",oct,16 + oct- 0x4a);
3956         if (( oct >= 0xbb ) && ( oct <= 0xfa ))
3957                 proto_tree_add_text(tree,
3958                         tvb, curr_offset, 1,
3959                         "Maximum bit rate for uplink (extended): (%u) %uMbps",oct,128 + oct - 0xba * 2);
3960         else
3961                 proto_tree_add_text(tree,
3962                         tvb, curr_offset, 1,
3963                         "Maximum bit rate for uplink (extended): (%u) %s",oct,str);
3964
3965         curr_offset+= 1;
3966         curr_len-= 1;
3967
3968         if ( curr_len == 0 )
3969         {
3970                 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3971
3972                 return(curr_offset - offset);
3973         }
3974
3975         /* Guaranteed bit rate for uplink (extended) Octet 18 */
3976         oct = tvb_get_guint8(tvb, curr_offset);
3977
3978         switch ( oct )
3979         {
3980                 case 0x00: str="Use the value indicated by the Guaranteed bit rate for uplink"; break;
3981                 default: str="Unspecified";
3982         }
3983
3984         if (( oct >= 1 ) && ( oct <= 0x4a ))
3985                 proto_tree_add_text(tree,
3986                         tvb, curr_offset, 1,
3987                         "Guaranteed bit rate for uplink (extended): (%u) %ukbps",oct,oct*100);
3988         if (( oct >= 0x4b ) && ( oct <= 0xba ))
3989                 proto_tree_add_text(tree,
3990                         tvb, curr_offset, 1,
3991                         "Guaranteed bit rate for uplink (extended): (%u) %uMbps",oct,16 + oct- 0x4a);
3992         if (( oct >= 0xbb ) && ( oct <= 0xfa ))
3993                 proto_tree_add_text(tree,
3994                         tvb, curr_offset, 1,
3995                         "Guaranteed bit rate for uplink (extended): (%u) %uMbps",oct,128 + oct - 0xba * 2);
3996         else
3997                 proto_tree_add_text(tree,
3998                         tvb, curr_offset, 1,
3999                         "Guaranteed bit rate for uplink (extended): (%u) %s",oct,str);
4000
4001         curr_offset+= 1;
4002         curr_len-= 1;
4003         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4004
4005         return(curr_offset - offset);
4006 }
4007
4008 /*
4009  * [8] 10.5.6.6 SM cause
4010  */
4011 static guint16
4012 de_sm_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len _U_)
4013 {
4014         guint8  oct;
4015         guint32 curr_offset;
4016         const gchar     *str;
4017
4018         curr_offset = offset;
4019
4020         oct = tvb_get_guint8(tvb, curr_offset);
4021
4022         switch ( oct )
4023         {
4024                 case 0x08: str="Operator Determined Barring"; break;
4025                 case 0x18: str="MBMS bearer capabilities insufficient for the service"; break;
4026                 case 0x19: str="LLC or SNDCP failure(GSM only)"; break;
4027                 case 0x1a: str="Insufficient resources"; break;
4028                 case 0x1b: str="Missing or unknown APN"; break;
4029                 case 0x1c: str="Unknown PDP address or PDP type"; break;
4030                 case 0x1d: str="User Authentication failed"; break;
4031                 case 0x1e: str="Activation rejected by GGSN"; break;
4032                 case 0x1f: str="Activation rejected, unspecified"; break;
4033                 case 0x20: str="Service option not supported"; break;
4034                 case 0x21: str="Requested service option not subscribed"; break;
4035                 case 0x22: str="Service option temporarily out of order"; break;
4036                 case 0x23: str="NSAPI already used (not sent)"; break;
4037                 case 0x24: str="Regular deactivation"; break;
4038                 case 0x25: str="QoS not accepted"; break;
4039                 case 0x26: str="Network failure"; break;
4040                 case 0x27: str="Reactivation required"; break;
4041                 case 0x28: str="Feature not supported"; break;
4042                 case 0x29: str="Semantic error in the TFT operation"; break;
4043                 case 0x2a: str="Syntactical error in the TFT operation"; break;
4044                 case 0x2b: str="Unknown PDP context"; break;
4045                 case 0x2e: str="PDP context without TFT already activated"; break;
4046                 case 0x2f: str="Multicast group membership time-out"; break;
4047                 case 0x2c: str="Semantic errors in packet filter(s)"; break;
4048                 case 0x2d: str="Syntactical errors in packet filter(s)"; break;
4049                 case 0x51: str="Invalid transaction identifier value"; break;
4050                 case 0x5f: str="Semantically incorrect message"; break;
4051                 case 0x60: str="Invalid mandatory information"; break;
4052                 case 0x61: str="Message type non-existent or not implemented"; break;
4053                 case 0x62: str="Message type not compatible with the protocol state"; break;
4054                 case 0x63: str="Information element non-existent or not implemented"; break;
4055                 case 0x64: str="Conditional IE error"; break;
4056                 case 0x65: str="Message not compatible with the protocol state"; break;
4057                 case 0x6f: str="Protocol error, unspecified"; break;
4058                 case 0x70: str="APN restriction value incompatible with active PDP context"; break;
4059                 default: str="Protocol error, unspecified"; break;
4060         }
4061
4062         proto_tree_add_text(tree,
4063                 tvb, curr_offset, 1,
4064                 "Cause: (%u) %s %s",
4065                 oct, str,add_string ? add_string : "");
4066
4067         curr_offset++;
4068
4069         return(curr_offset - offset);
4070 }
4071
4072 /*
4073  * [7] 10.5.6.7
4074  */
4075 static guint16
4076 de_sm_linked_ti(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4077 {
4078         guint32 curr_offset;
4079         guint   curr_len;
4080         gchar   oct;
4081
4082         static const gchar *ti_flag[2]={
4083                 "The message is sent from the side that originates the TI" ,
4084                 "The message is sent to the side that originates the TI" };
4085
4086         curr_len = len;
4087         curr_offset = offset;
4088
4089         oct = tvb_get_guint8(tvb, curr_offset);
4090
4091         proto_tree_add_text(tree,
4092                 tvb, curr_offset, 1,
4093                 "TI flag: (%u) %s",oct>>7,ti_flag[oct>>7]);
4094
4095         if ( curr_len > 1 )
4096         {
4097                 oct = tvb_get_guint8(tvb, curr_offset);
4098
4099                 proto_tree_add_text(tree,
4100                         tvb, curr_offset, 1,
4101                         "TI value: 0x%02x (%u)",oct&0x7f,oct&0x7f);
4102
4103                 proto_tree_add_text(tree,
4104                         tvb, curr_offset, 1,
4105                         "ext: 0x%02x (%u)",oct>>7,oct>>7);
4106
4107         }
4108         else
4109         {
4110                 proto_tree_add_text(tree,
4111                         tvb, curr_offset, 1,
4112                         "TI value: 0x%02x (%u)",(oct>>4)&7,(oct>>4)&7);
4113         }
4114
4115         curr_offset+= curr_len;
4116            
4117         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4118
4119         return(curr_offset - offset);
4120 }
4121
4122 /*
4123  * [7] 10.5.6.9
4124  */
4125 static guint16
4126 de_sm_sapi(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len _U_)
4127 {
4128         guint8  oct;
4129         guint32 curr_offset;
4130
4131         curr_offset = offset;
4132
4133         oct = tvb_get_guint8(tvb, curr_offset);
4134
4135         proto_tree_add_text(tree,
4136                 tvb, curr_offset, 1,
4137                 "LLC SAPI: 0x%02x (%u) %s",
4138                 oct&0x0f, oct&0x0f,add_string ? add_string : "");
4139
4140         curr_offset++;
4141
4142         return(curr_offset - offset);
4143 }
4144
4145 /*
4146  * [7] 10.5.6.10
4147  */
4148 static guint16
4149 de_sm_tear_down(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len _U_)
4150 {
4151         guint8  oct;
4152         guint32 curr_offset;
4153         static const gchar *str[2] = {
4154                 "tear down not requested" ,
4155                 "tear down requested" };
4156
4157         curr_offset = offset;
4158
4159         oct = tvb_get_guint8(tvb, curr_offset);
4160
4161         proto_tree_add_text(tree,
4162                 tvb, curr_offset, 1,
4163                 "Tear Down Indicator: (%u) %s %s",
4164                 oct&1, str[oct&1],add_string ? add_string : "");
4165
4166         curr_offset++;
4167
4168         return(curr_offset - offset);
4169 }
4170
4171 /*
4172  * [7] 10.5.6.11
4173  */
4174 /* Packet Flow Identifier value (octet 3) */
4175 static const value_string gsm_a_packet_flow_id_vals[] = {
4176         { 0,            "Best Effort"},
4177         { 1,            "Signaling"},
4178         { 2,            "SMS"},
4179         { 3,            "TOM8"},
4180         { 4,            "reserved"},
4181         { 5,            "reserved"},
4182         { 6,            "reserved"},
4183         { 7,            "reserved"},
4184         { 0,    NULL }
4185 };
4186 guint16
4187 de_sm_pflow_id(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4188 {
4189         guint32 curr_offset;
4190         guint   curr_len;
4191         guchar  oct;
4192
4193         curr_len = len;
4194         curr_offset = offset;
4195
4196         oct = tvb_get_guint8(tvb, curr_offset);
4197
4198         proto_tree_add_text(tree,
4199                 tvb, curr_offset, 1,
4200                 "Packet Flow Identifier: (%u) %s",oct&0x7f,
4201                 val_to_str(oct&0x7f, gsm_a_packet_flow_id_vals, "dynamically assigned (%u)"));
4202
4203         curr_offset+= curr_len;
4204            
4205         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4206
4207         return(curr_offset - offset);
4208 }
4209
4210 /*
4211  * [7] 10.5.6.12     TFT - Traffic Flow Template
4212  */
4213 /* TFT operation code (octet 3) */
4214 static const value_string gsm_a_tft_op_code_vals[] = {
4215         { 0,            "Spare"},
4216         { 1,            "Create new TFT"},
4217         { 2,            "Delete existing TFT"},
4218         { 3,            "Add packet filters to existing TFT"},
4219         { 4,            "Replace packet filters in existing TFT"},
4220         { 5,            "Delete packet filters from existing TFT"},
4221         { 6,            "No TFT operation"},
4222         { 7,            "Reserved"},
4223         { 0,    NULL }
4224 };
4225
4226 static const true_false_string gsm_a_tft_e_bit  = {
4227   "parameters list is included",
4228   "parameters list is not included"
4229 };
4230
4231
4232 static guint16
4233 de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
4234 {
4235         guint32       curr_offset;
4236         guint         curr_len;
4237         proto_item   *tf = NULL;
4238         proto_tree   *tf_tree = NULL;
4239         proto_tree   *comp_tree = NULL;
4240         guchar        op_code;
4241         guchar        pkt_fil_count;
4242         guchar        e_bit;
4243         const gchar  *str;
4244         guchar        count;
4245         guchar        oct;
4246         gint          pf_length;
4247         gint          pf_identifier;
4248         gint          pack_component_type;
4249
4250         curr_len = len;
4251         curr_offset = offset;
4252
4253         /*
4254          * parse first octet. It contain TFT operation code, E bit and Number of packet filters
4255          */
4256         oct = tvb_get_guint8(tvb, curr_offset);
4257
4258         op_code = oct>>5;
4259         pkt_fil_count = oct&0x0f;
4260         e_bit = (oct>>4)&1;
4261
4262         proto_tree_add_item(tree,hf_gsm_a_tft_op_code,tvb,curr_offset,1,FALSE);
4263         proto_tree_add_item(tree,hf_gsm_a_tft_e_bit,tvb,curr_offset,1,FALSE);
4264         proto_tree_add_item(tree,hf_gsm_a_tft_pkt_flt,tvb,curr_offset,1,FALSE);
4265
4266         curr_offset++;
4267         curr_len--;
4268
4269         /* Packet filter list dissect */
4270
4271         count = 0;
4272         if ( op_code == 2 )                     /* delete TFT contains no packet filters. so we will jump over it */
4273                 count = pkt_fil_count;
4274         while ( count < pkt_fil_count )
4275         {
4276                 tf = proto_tree_add_text(tree,
4277                         tvb, curr_offset, 1,
4278                         "Packet filter %d",count);   /* 0-> 7 */
4279
4280                 tf_tree = proto_item_add_subtree(tf, ett_sm_tft );
4281
4282                 if ( op_code == 5 )  /* Delete packet filters from existing TFT - just a list of identifiers */
4283                 {
4284                         if ((curr_offset-offset)<1) {
4285                                 proto_tree_add_text(tf_tree,tvb, curr_offset, 1,"Not enough data");
4286                                 return(curr_offset-offset);
4287                         }
4288                         oct = tvb_get_guint8(tvb, curr_offset);
4289                         curr_offset++;
4290                         curr_len--;
4291
4292                         proto_tree_add_text(tf_tree,
4293                                 tvb, curr_offset-1, 1,
4294                                 "Packet filter identifier: 0x%02x (%u)",oct,oct );      
4295                 }
4296                 else                            /* create new, Add packet filters or Replace packet filters */
4297                 {
4298
4299                         if ((curr_offset-offset)<1) {
4300                                 proto_tree_add_text(tf_tree,tvb, curr_offset, 1,"Not enough data");
4301                                 return(curr_offset-offset);
4302                         }
4303                         pf_identifier = tvb_get_guint8(tvb, curr_offset);
4304                         curr_offset++;
4305                         curr_len--;
4306
4307                         proto_tree_add_text(tf_tree,
4308                                 tvb, curr_offset-1, 1,
4309                                 "Packet filter identifier: %u (%u)",pf_identifier, pf_identifier);      
4310
4311                         if ((curr_offset-offset)<1) {
4312                                 proto_tree_add_text(tf_tree,tvb, curr_offset, 1,"Not enough data");
4313                                 return(curr_offset-offset);
4314                         }
4315                         oct = tvb_get_guint8(tvb, curr_offset);
4316                         curr_offset++;
4317                         curr_len--;
4318
4319                         proto_tree_add_text(tf_tree,
4320                                 tvb, curr_offset-1, 1,
4321                                 "Packet evaluation precedence: 0x%02x (%u)",oct,oct );  
4322
4323                         if ((curr_offset-offset)<1) { proto_tree_add_text(tf_tree,tvb, curr_offset, 1,"Not enough data"); return(curr_offset-offset);}
4324                         pf_length = tvb_get_guint8(tvb, curr_offset);
4325                         curr_offset++;
4326                         curr_len--;
4327
4328                         proto_tree_add_text(tf_tree,
4329                                 tvb, curr_offset-1, 1,
4330                                 "Packet filter length: 0x%02x (%u)",pf_length,pf_length );      
4331                         /* New tree for component */
4332
4333                         /* Dissect Packet filter Component */
4334                         /* while ( filter_len > 1 ) */
4335                         /* packet filter component type identifier: */
4336
4337                         if (pf_length > 0 ){
4338                                 if ((curr_offset-offset)<1) {
4339                                         proto_tree_add_text(tf_tree,tvb, curr_offset, 1,"Not enough data");
4340                                         return(curr_offset-offset);
4341                                 }
4342                                 pack_component_type = tvb_get_guint8(tvb, curr_offset);
4343                                 curr_offset++;
4344                                 curr_len--;
4345
4346                                 tf=proto_tree_add_text(tf_tree,tvb, curr_offset-1, 1,"Packet filter component type identifier: ");
4347                                 comp_tree = proto_item_add_subtree(tf, ett_sm_tft );
4348
4349                                 switch ( pack_component_type ){
4350                         
4351                                 case 0x10:
4352                                         str="IPv4 source address type";
4353                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_ip4_address,tvb,curr_offset,4,FALSE);
4354                                         curr_offset+=4;
4355                                         curr_len-=4;
4356                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_ip4_mask,tvb,curr_offset,4,FALSE);
4357                                         curr_offset+=4;
4358                                         curr_len-=4;
4359                                         break;
4360
4361                                 case 0x20:
4362                                         str="IPv6 source address type";
4363                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_ip6_address,tvb,curr_offset,16,FALSE);
4364                                         curr_offset+=16;
4365                                         curr_len-=16;
4366                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_ip6_mask,tvb,curr_offset,16,FALSE);
4367                                         curr_offset+=16;
4368                                         curr_len-=16;
4369                                         break;
4370
4371                                 case 0x30:
4372                                         str="Protocol identifier/Next header type";
4373                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_protocol_header,tvb,curr_offset,1,FALSE);
4374                                         curr_offset+=1;
4375                                         curr_len-=1;
4376                                         break;
4377
4378                                 case 0x40:
4379                                         str="Single destination port type";
4380                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_port,tvb,curr_offset,2,FALSE);
4381                                         curr_offset+=2;
4382                                         curr_len-=2;
4383
4384                                 case 0x41:
4385                                         str="Destination port range type";
4386                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_port_low,tvb,curr_offset,2,FALSE);
4387                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_port_high,tvb,curr_offset,2,FALSE);
4388                                         curr_offset+=4;
4389                                         curr_len-=4;
4390                                         break;
4391
4392                                 case 0x50:
4393                                         str="Single source port type";
4394                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_port,tvb,curr_offset,2,FALSE);
4395                                         curr_offset+=2;
4396                                         curr_len-=2;
4397                                         break;
4398
4399                                 case 0x51:
4400                                         str="Source port range type";
4401                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_port_low,tvb,curr_offset,2,FALSE);
4402                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_port_high,tvb,curr_offset,2,FALSE);
4403                                         curr_offset+=4;
4404                                         curr_len-=4;
4405                                         break;
4406
4407                                 case 0x60:
4408                                         str="Security parameter index type";
4409                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_security,tvb,curr_offset,4,FALSE);
4410                                         curr_offset+=4;
4411                                         curr_len-=4;
4412                                         break;
4413
4414
4415                                 case 0x70:
4416                                         str="Type of service/Traffic class type";
4417                                         proto_tree_add_item(comp_tree,hf_gsm_a_qos_traffic_cls,tvb,curr_offset,1,FALSE);
4418                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_traffic_mask,tvb,curr_offset,1,FALSE);
4419                                         curr_offset+=2;
4420                                         curr_len-=2;
4421                                         break;
4422
4423                                 case 0x80:
4424                                         str="Flow label type";
4425                                         proto_tree_add_item(comp_tree,hf_gsm_a_tft_traffic_mask,tvb,curr_offset,1,FALSE);
4426                                         curr_offset+=3;
4427                                         curr_len-=3;
4428                                         break;
4429
4430                                 default:
4431                                         str="not specified";
4432                                 }
4433                                 proto_item_append_text(tf, "(%u) %s", pack_component_type, str );
4434                                 count++;
4435                         }
4436                 }
4437         }
4438
4439         /* The parameters list contains a variable number of parameters that might need to be
4440          * transferred in addition to the packet filters. If the parameters list is included, the E
4441          * bit is set to 1; otherwise, the E bit is set to 0.
4442          */
4443         if (e_bit == 1){
4444                  proto_tree_add_text(tf_tree, tvb, curr_offset, 1, "Note: Possible Authorization Token/Flow Identifier not decoded yet");
4445         }
4446         return(curr_offset - offset);
4447 }
4448
4449 guint16 (*gm_elem_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len) = {
4450         /* GPRS Mobility Management Information Elements 10.5.5 */
4451         de_gmm_attach_res,      /* Attach Result */
4452         de_gmm_attach_type,     /* Attach Type */
4453         de_gmm_ciph_alg,        /* Cipher Algorithm */
4454         de_gmm_tmsi_stat,       /* TMSI Status */
4455         de_gmm_detach_type,     /* Detach Type */
4456         de_gmm_drx_param,       /* DRX Parameter */
4457         de_gmm_ftostby,         /* Force to Standby */
4458         de_gmm_ftostby_h,       /* Force to Standby - Info is in the high nibble */
4459         de_gmm_ptmsi_sig,       /* P-TMSI Signature */
4460         de_gmm_ptmsi_sig2,      /* P-TMSI Signature 2 */
4461         de_gmm_ident_type2,     /* Identity Type 2 */
4462         de_gmm_imeisv_req,      /* IMEISV Request */
4463         de_gmm_rec_npdu_lst,    /* Receive N-PDU Numbers List */
4464         de_gmm_ms_net_cap,      /* MS Network Capability */
4465         de_gmm_ms_radio_acc_cap,/* MS Radio Access Capability */
4466         de_gmm_cause,           /* GMM Cause */
4467         de_gmm_rai,             /* Routing Area Identification */
4468         de_gmm_update_res,      /* Update Result */
4469         de_gmm_update_type,     /* Update Type */
4470         de_gmm_ac_ref_nr,       /* A&C Reference Number */
4471         de_gmm_ac_ref_nr_h,     /* A&C Reference Numer - Info is in the high nibble */
4472         de_gmm_service_type,    /* Service Type */
4473         NULL /* no associated data */,  /* Cell Notification */
4474         de_gmm_ps_lcs_cap,      /* PS LCS Capability */
4475         de_gmm_net_feat_supp,   /* Network Feature Support */
4476         de_gmm_rat_info_container, /* Inter RAT information container */
4477         /* Session Management Information Elements 10.5.6 */
4478         de_sm_apn,              /* Access Point Name */
4479         de_sm_nsapi,            /* Network Service Access Point Identifier */
4480         de_sm_pco,              /* Protocol Configuration Options */
4481         de_sm_pdp_addr,         /* Packet Data Protocol Address */
4482         de_sm_qos,              /* Quality Of Service */
4483         de_sm_cause,            /* SM Cause */
4484         de_sm_linked_ti,        /* Linked TI */
4485         de_sm_sapi,             /* LLC Service Access Point Identifier */
4486         de_sm_tear_down,        /* Tear Down Indicator */
4487         de_sm_pflow_id,         /* Packet Flow Identifier */
4488         de_sm_tflow_temp,       /* Traffic Flow Template */
4489         /* GPRS Common Information Elements 10.5.7 */
4490         de_gc_context_stat,     /* PDP Context Status */
4491         de_gc_radio_prio,       /* Radio Priority */
4492         de_gc_timer,            /* GPRS Timer */
4493         de_gc_timer2,           /* GPRS Timer 2 */
4494         de_gc_radio_prio2,      /* Radio Priority 2 */
4495         de_gc_mbms_context_stat,/* 10.5.7.6 MBMS context status */
4496         NULL,   /* NONE */
4497 };
4498
4499 /* MESSAGE FUNCTIONS */
4500
4501 /*
4502  * [7] 9.4.1
4503  */
4504 static void
4505 dtap_gmm_attach_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4506 {
4507         guint32 curr_offset;
4508         guint32 consumed;
4509         guint   curr_len;
4510
4511         curr_offset = offset;
4512         curr_len = len;
4513
4514         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_RECV;
4515
4516         ELEM_MAND_LV(GSM_A_PDU_TYPE_GM, DE_MS_NET_CAP, NULL);
4517
4518         /* Included in attach type
4519
4520         ELEM_MAND_V(GSM_A_PDU_TYPE_COMMON, DE_CIPH_KEY_SEQ_NUM );
4521         curr_offset--;
4522         curr_len++;
4523         */
4524
4525         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_ATTACH_TYPE );
4526
4527         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_DRX_PARAM );
4528
4529         ELEM_MAND_LV(GSM_A_PDU_TYPE_COMMON, DE_MID , NULL);
4530
4531         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_RAI );
4532
4533         ELEM_MAND_LV(GSM_A_PDU_TYPE_GM, DE_MS_RAD_ACC_CAP , NULL);
4534
4535         ELEM_OPT_TV( 0x19 , GSM_A_PDU_TYPE_GM, DE_P_TMSI_SIG, " - Old P-TMSI Signature");
4536
4537         ELEM_OPT_TV( 0x17 , GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER , " - Ready Timer" );
4538
4539         ELEM_OPT_TV_SHORT( 0x90 , GSM_A_PDU_TYPE_GM, DE_TMSI_STAT , NULL);
4540
4541         ELEM_OPT_TLV( 0x33 , GSM_A_PDU_TYPE_GM, DE_PS_LCS_CAP , NULL);
4542
4543         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4544 }
4545
4546 /*
4547  * [7] 9.4.2
4548  */
4549 static void
4550 dtap_gmm_attach_acc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4551 {
4552         guint32 curr_offset;
4553         guint32 consumed;
4554         guint   curr_len;
4555
4556         curr_offset = offset;
4557         curr_len = len;
4558
4559         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_SENT;
4560
4561         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND_H );
4562         curr_len++;
4563         curr_offset--;
4564
4565         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_ATTACH_RES );
4566
4567         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER );
4568
4569         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_RAD_PRIO_2 );
4570         curr_len++;
4571         curr_offset--;
4572
4573         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_RAD_PRIO );
4574
4575         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_RAI );
4576
4577         ELEM_OPT_TV( 0x19 , GSM_A_PDU_TYPE_GM, DE_P_TMSI_SIG, NULL);
4578
4579         ELEM_OPT_TV( 0x17 , GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER , " - Negotiated Ready Timer" );
4580
4581         ELEM_OPT_TLV( 0x18 , GSM_A_PDU_TYPE_COMMON, DE_MID , " - Allocated P-TMSI" );
4582
4583         ELEM_OPT_TLV( 0x23 , GSM_A_PDU_TYPE_COMMON, DE_MID , NULL);
4584
4585         ELEM_OPT_TV( 0x25 , GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE , NULL);
4586
4587         ELEM_OPT_TLV( 0x2A , GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_2 , " - T3302" );
4588
4589         ELEM_OPT_T( 0x8C , GSM_A_PDU_TYPE_GM, DE_CELL_NOT , NULL);
4590
4591         ELEM_OPT_TLV( 0x4A , GSM_A_PDU_TYPE_COMMON, DE_PLMN_LIST , NULL);
4592
4593         ELEM_OPT_TV_SHORT( 0xB0 , GSM_A_PDU_TYPE_GM, DE_NET_FEAT_SUP , NULL);
4594
4595         ELEM_OPT_TLV( 0x34 , GSM_A_PDU_TYPE_DTAP, DE_EMERGENCY_NUM_LIST , NULL);
4596
4597         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4598 }
4599
4600 /*
4601  * [7] 9.4.3
4602  */
4603 static void
4604 dtap_gmm_attach_com(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4605 {
4606
4607         guint32 curr_offset;
4608 /*    guint32   consumed; */
4609         guint   curr_len;
4610
4611         curr_offset = offset;
4612         curr_len = len;
4613
4614         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_RECV;
4615
4616         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4617 }
4618
4619 /*
4620  * [7] 9.4.4
4621  */
4622 static void
4623 dtap_gmm_attach_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4624 {
4625         guint32 curr_offset;
4626         guint32 consumed;
4627         guint   curr_len;
4628
4629         curr_offset = offset;
4630         curr_len = len;
4631
4632         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_SENT;
4633
4634         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE );
4635
4636         ELEM_OPT_TLV( 0x2A , GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_2 , " - T3302" );
4637
4638         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4639 }
4640
4641 /*
4642  * [7] 9.4.5
4643  */
4644 static void
4645 dtap_gmm_detach_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4646 {
4647         guint32 curr_offset;
4648         guint32 consumed;
4649         guint   curr_len;
4650
4651         curr_offset = offset;
4652         curr_len = len;
4653
4654         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_SENT;
4655
4656         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND_H );
4657         /* Force to standy might be wrong - To decode it correct, we need the direction */
4658         curr_len++;
4659         curr_offset--;
4660
4661         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_DETACH_TYPE );
4662
4663         ELEM_OPT_TV( 0x25 , GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE , NULL);
4664
4665         ELEM_OPT_TLV( 0x18 , GSM_A_PDU_TYPE_COMMON, DE_MID , " - P-TMSI" );
4666
4667         ELEM_OPT_TLV( 0x19 , GSM_A_PDU_TYPE_GM, DE_P_TMSI_SIG , NULL);
4668
4669         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4670 }
4671
4672 /*
4673  * [7] 9.4.6
4674  */
4675 static void
4676 dtap_gmm_detach_acc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4677 {
4678         guint32 curr_offset;
4679         guint32 consumed;
4680         guint   curr_len;
4681
4682         curr_offset = offset;
4683         curr_len = len;
4684
4685         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_RECV;
4686
4687         if ( curr_len != 0 )
4688         {
4689                 ELEM_MAND_V(GSM_A_PDU_TYPE_COMMON, DE_SPARE_NIBBLE );
4690                 curr_len++;
4691                 curr_offset--;
4692         
4693                 ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND );
4694         }
4695
4696         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4697 }
4698
4699 /*
4700  * [7] 9.4.7
4701  */
4702 static void
4703 dtap_gmm_ptmsi_realloc_cmd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4704 {
4705         guint32 curr_offset;
4706         guint32 consumed;
4707         guint   curr_len;
4708
4709         curr_offset = offset;
4710         curr_len = len;
4711
4712         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_SENT;
4713
4714         ELEM_MAND_LV(GSM_A_PDU_TYPE_COMMON, DE_MID , " - Allocated P-TMSI" );
4715
4716         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_RAI );
4717
4718         ELEM_MAND_V(GSM_A_PDU_TYPE_COMMON, DE_SPARE_NIBBLE );
4719         curr_len++;
4720         curr_offset--;
4721
4722         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND );
4723
4724         ELEM_OPT_TV( 0x19 , GSM_A_PDU_TYPE_COMMON, DE_MID , " - P-TMSI Signature" );
4725
4726         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4727 }
4728
4729 /*
4730  * [7] 9.4.8
4731  */
4732 static void
4733 dtap_gmm_ptmsi_realloc_com(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4734 {
4735         guint32 curr_offset;
4736 /*    guint32   consumed; */
4737         guint   curr_len;
4738
4739         curr_offset = offset;
4740         curr_len = len;
4741
4742         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_RECV;
4743
4744         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4745 }
4746
4747 /*
4748  * [7] 9.4.9
4749  */
4750 static void
4751 dtap_gmm_auth_ciph_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4752 {
4753         guint32 curr_offset;
4754         guint32 consumed;
4755         guint   curr_len;
4756         guint8  oct;
4757
4758         curr_offset = offset;
4759         curr_len = len;
4760
4761         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_SENT;
4762
4763         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_IMEISV_REQ );
4764         curr_offset--;
4765         curr_len++;
4766
4767         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_CIPH_ALG );
4768
4769         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_AC_REF_NUM_H );
4770         curr_offset--;
4771         curr_len++;
4772
4773         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND );
4774
4775         ELEM_OPT_TV( 0x21 , GSM_A_PDU_TYPE_DTAP, DE_AUTH_PARAM_RAND , NULL);
4776
4777 #if 0
4778         ELEM_OPT_TV_SHORT( 0x08 , GSM_A_PDU_TYPE_COMMON, DE_CIPH_KEY_SEQ_NUM , NULL);
4779 #else
4780         if ( curr_len > 0 )
4781         {
4782                 oct = tvb_get_guint8(tvb, curr_offset);
4783                 if (( oct & 0xf0 ) == 0x80 )
4784                 {
4785                         /* The ciphering key sequence number is added here */
4786                         proto_tree_add_text(tree,
4787                                 tvb, curr_offset, 1,
4788                                 "Ciphering key sequence number: 0x%02x (%u)",
4789                                 oct&7,
4790                                 oct&7);
4791                         curr_offset++;
4792                         curr_len--;
4793                 }
4794         }
4795 #endif
4796
4797         if ( curr_len == 0  )
4798         {
4799                 EXTRANEOUS_DATA_CHECK(curr_len, 0);
4800         return;
4801         }
4802         
4803         ELEM_OPT_TLV( 0x28 , GSM_A_PDU_TYPE_DTAP, DE_AUTH_PARAM_AUTN , NULL);
4804
4805         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4806 }
4807
4808 /*
4809  * [7] 9.4.10
4810  */
4811 static void
4812 dtap_gmm_auth_ciph_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4813 {
4814         guint32 curr_offset;
4815         guint32 consumed;
4816         guint   curr_len;
4817
4818         curr_offset = offset;
4819         curr_len = len;
4820
4821         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_RECV;
4822
4823         ELEM_MAND_V(GSM_A_PDU_TYPE_COMMON, DE_SPARE_NIBBLE );
4824         curr_offset--;
4825         curr_len++;
4826
4827         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_AC_REF_NUM );
4828
4829         ELEM_OPT_TV( 0x22 , GSM_A_PDU_TYPE_DTAP, DE_AUTH_RESP_PARAM , NULL);
4830
4831         ELEM_OPT_TLV( 0x23 , GSM_A_PDU_TYPE_COMMON, DE_MID , " - IMEISV" );
4832
4833         ELEM_OPT_TLV( 0x29 , GSM_A_PDU_TYPE_DTAP, DE_AUTH_RESP_PARAM_EXT , NULL);
4834
4835         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4836 }
4837
4838 /*
4839  * [7] 9.4.11
4840  */
4841 static void
4842 dtap_gmm_auth_ciph_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4843 {
4844         guint32 curr_offset;
4845         guint   curr_len;
4846
4847         curr_offset = offset;
4848         curr_len = len;
4849
4850         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_SENT;
4851
4852         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4853 }
4854
4855 /*
4856  * [7] 9.4.10a
4857  */
4858 static void
4859 dtap_gmm_auth_ciph_fail(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4860 {
4861         guint32 curr_offset;
4862         guint32 consumed;
4863         guint   curr_len;
4864
4865         curr_offset = offset;
4866         curr_len = len;
4867
4868         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_RECV;
4869
4870         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE );
4871
4872         ELEM_OPT_TLV( 0x30 , GSM_A_PDU_TYPE_DTAP, DE_AUTH_FAIL_PARAM , NULL);
4873
4874         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4875 }
4876
4877 /*
4878  * [7] 9.4.12
4879  */
4880 static void
4881 dtap_gmm_ident_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4882 {
4883         guint32 curr_offset;
4884         guint   curr_len;
4885
4886         curr_offset = offset;
4887         curr_len = len;
4888
4889         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_SENT;
4890
4891 /*  If the half octect that are about to get decoded is the LAST in the octetstream, the macro will call return BEFORE we get a chance to fix the index. The end result will be that the first half-octet will be decoded but not the last. */
4892 #if 0
4893         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_ID_TYPE_2 );
4894         curr_offset--;
4895         curr_len++;
4896         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND_H );
4897 #endif
4898
4899         elem_v(tvb, tree, GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND_H, curr_offset);
4900         elem_v(tvb, tree, GSM_A_PDU_TYPE_GM, DE_ID_TYPE_2, curr_offset);
4901
4902         curr_offset+=1;
4903         curr_len-=1;
4904
4905         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4906 }
4907
4908 /*
4909  * [7] 9.4.13
4910  */
4911 static void
4912 dtap_gmm_ident_res(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4913 {
4914         guint32 curr_offset;
4915         guint32 consumed;
4916         guint   curr_len;
4917
4918         curr_offset = offset;
4919         curr_len = len;
4920
4921         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_RECV;
4922
4923         ELEM_MAND_LV(GSM_A_PDU_TYPE_COMMON, DE_MID , NULL);
4924
4925         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4926 }
4927
4928 /*
4929  * [7] 9.4.14
4930  */
4931 static void
4932 dtap_gmm_rau_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4933 {
4934         guint32 curr_offset;
4935         guint32 consumed;
4936         guint   curr_len;
4937
4938         curr_offset = offset;
4939         curr_len = len;
4940
4941         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_RECV;
4942
4943         /* is included in update type
4944         ELEM_MAND_V(GSM_A_PDU_TYPE_COMMON, DE_CIPH_KEY_SEQ_NUM );
4945         curr_offset--;
4946         curr_len++;
4947         */
4948
4949         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_UPD_TYPE );
4950
4951         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_RAI );
4952
4953         ELEM_MAND_LV(GSM_A_PDU_TYPE_GM, DE_MS_RAD_ACC_CAP , NULL);
4954
4955         ELEM_OPT_TV( 0x19 , GSM_A_PDU_TYPE_GM, DE_P_TMSI_SIG , " - Old P-TMSI Signature" );
4956
4957         ELEM_OPT_TV( 0x17 , GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER , " - Requested Ready Timer" );
4958
4959         ELEM_OPT_TV( 0x27 , GSM_A_PDU_TYPE_GM, DE_DRX_PARAM , NULL);
4960
4961         ELEM_OPT_TV_SHORT( 0x90 , GSM_A_PDU_TYPE_GM, DE_TMSI_STAT , NULL);
4962
4963         ELEM_OPT_TLV( 0x18 , GSM_A_PDU_TYPE_COMMON, DE_MID , " - P-TMSI" );
4964
4965         ELEM_OPT_TLV( 0x31 , GSM_A_PDU_TYPE_GM, DE_MS_NET_CAP , NULL);
4966
4967         ELEM_OPT_TLV( 0x32 , GSM_A_PDU_TYPE_GM, DE_PDP_CONTEXT_STAT , NULL);
4968
4969         ELEM_OPT_TLV( 0x33 , GSM_A_PDU_TYPE_GM, DE_PS_LCS_CAP , NULL);
4970
4971         EXTRANEOUS_DATA_CHECK(curr_len, 0);
4972 }
4973
4974 /*
4975  * [7] 9.4.15
4976  */
4977 static void
4978 dtap_gmm_rau_acc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
4979 {
4980         guint32 curr_offset;
4981         guint32 consumed;
4982         guint   curr_len;
4983
4984         curr_offset = offset;
4985         curr_len = len;
4986
4987         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_SENT;
4988
4989         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_UPD_RES );
4990         curr_offset--;
4991         curr_len++;
4992
4993         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND );
4994
4995         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER );
4996
4997         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_RAI );
4998
4999         ELEM_OPT_TV( 0x19 , GSM_A_PDU_TYPE_GM, DE_P_TMSI_SIG , NULL);
5000
5001         ELEM_OPT_TLV( 0x18 , GSM_A_PDU_TYPE_COMMON, DE_MID , " - Allocated P-TMSI");
5002
5003         ELEM_OPT_TLV( 0x23 , GSM_A_PDU_TYPE_COMMON, DE_MID , NULL);
5004
5005         ELEM_OPT_TLV( 0x26 , GSM_A_PDU_TYPE_GM, DE_REC_N_PDU_NUM_LIST , NULL);
5006
5007         ELEM_OPT_TV( 0x17 , GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER , " - Negotiated Ready Timer" );
5008
5009         ELEM_OPT_TV( 0x25 , GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE , NULL);
5010
5011         ELEM_OPT_TLV( 0x2A , GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_2 , " - T3302" );
5012
5013         ELEM_OPT_T( 0x8C , GSM_A_PDU_TYPE_GM, DE_CELL_NOT , NULL);
5014
5015         ELEM_OPT_TLV( 0x4A , GSM_A_PDU_TYPE_COMMON, DE_PLMN_LIST , NULL);
5016
5017         ELEM_OPT_TLV( 0x32 , GSM_A_PDU_TYPE_GM, DE_PDP_CONTEXT_STAT , NULL);
5018
5019         ELEM_OPT_TV_SHORT ( 0xB0 , GSM_A_PDU_TYPE_GM, DE_NET_FEAT_SUP , NULL);
5020
5021         ELEM_OPT_TLV( 0x34 , GSM_A_PDU_TYPE_DTAP, DE_EMERGENCY_NUM_LIST , NULL);
5022
5023         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5024 }
5025
5026 /*
5027  * [7] 9.4.16
5028  */
5029 static void
5030 dtap_gmm_rau_com(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5031 {
5032         guint32 curr_offset;
5033         guint32 consumed;
5034         guint   curr_len;
5035
5036         curr_offset = offset;
5037         curr_len = len;
5038
5039         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_RECV;
5040         /* [7] 10.5.5.11 */
5041         ELEM_OPT_TLV( 0x26 , GSM_A_PDU_TYPE_GM, DE_REC_N_PDU_NUM_LIST , NULL);
5042         /* Inter RAT information container 10.5.5.24 TS 24.008 version 6.8.0 Release 6 */
5043         /*TO DO: Implement */
5044         ELEM_OPT_TLV( 0x27 , GSM_A_PDU_TYPE_GM, DE_RAT_INFO_CONTAINER , NULL);
5045
5046         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5047 }
5048
5049 /*
5050  * [7] 9.4.17
5051  */
5052 static void
5053 dtap_gmm_rau_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5054 {
5055         guint32 curr_offset;
5056         guint32 consumed;
5057         guint   curr_len;
5058
5059         curr_offset = offset;
5060         curr_len = len;
5061
5062         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_SENT;
5063
5064         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE );
5065
5066         ELEM_MAND_V(GSM_A_PDU_TYPE_COMMON, DE_SPARE_NIBBLE );
5067         curr_offset--;
5068         curr_len++;
5069
5070         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_FORCE_TO_STAND );
5071
5072         ELEM_OPT_TLV( 0x26 , GSM_A_PDU_TYPE_GM, DE_GPRS_TIMER_2 , " - T3302" );
5073
5074         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5075 }
5076
5077 /*
5078  * [7] 9.4.18
5079  */
5080 static void
5081 dtap_gmm_status(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5082 {
5083         guint32 curr_offset;
5084         guint32 consumed;
5085         guint   curr_len;
5086
5087         curr_offset = offset;
5088         curr_len = len;
5089
5090         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
5091
5092         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE );
5093
5094         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5095 }
5096
5097 /*
5098  * [8] 9.4.19 GMM Information
5099  */
5100 static void
5101 dtap_gmm_information(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5102 {
5103         guint32 curr_offset;
5104         guint32 consumed;
5105         guint   curr_len;
5106
5107         curr_offset = offset;
5108         curr_len = len;
5109
5110         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_SENT;
5111
5112         ELEM_OPT_TLV( 0x43 , GSM_A_PDU_TYPE_DTAP, DE_NETWORK_NAME , " - Full Name" );
5113
5114         ELEM_OPT_TLV( 0x45 , GSM_A_PDU_TYPE_DTAP, DE_NETWORK_NAME , " - Short Name" );
5115
5116         ELEM_OPT_TV( 0x46 , GSM_A_PDU_TYPE_DTAP, DE_TIME_ZONE , NULL);
5117
5118         ELEM_OPT_TV( 0x47 , GSM_A_PDU_TYPE_DTAP, DE_TIME_ZONE_TIME , NULL);
5119
5120         ELEM_OPT_TLV( 0x48 , GSM_A_PDU_TYPE_DTAP, DE_LSA_ID , NULL);
5121
5122         ELEM_OPT_TLV( 0x49 , GSM_A_PDU_TYPE_DTAP, DE_DAY_SAVING_TIME , NULL);
5123
5124         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5125 }
5126
5127 /*
5128  * [7] 9.4.20
5129  */
5130 static void
5131 dtap_gmm_service_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5132 {
5133         guint32 curr_offset;
5134         guint32 consumed;
5135         guint   curr_len;
5136
5137         curr_offset = offset;
5138         curr_len = len;
5139
5140         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_RECV;
5141
5142         /* Is included in SRVC TYPE
5143         ELEM_MAND_V(GSM_A_PDU_TYPE_COMMON, DE_CIPH_KEY_SEQ_NUM );
5144         curr_offset--;
5145         curr_len++;
5146         */
5147
5148         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_SRVC_TYPE );
5149
5150         /* P-TMSI Mobile station identity 10.5.1.4 M LV 6 */
5151         ELEM_MAND_LV(GSM_A_PDU_TYPE_COMMON, DE_MID, NULL);
5152
5153         ELEM_OPT_TLV( 0x32 , GSM_A_PDU_TYPE_GM, DE_PDP_CONTEXT_STAT , NULL);
5154
5155         /* MBMS context status 10.5.7.6 TLV 2 - 18 */
5156         ELEM_OPT_TLV( 0x35 , GSM_A_PDU_TYPE_GM, DE_MBMS_CTX_STATUS , NULL);
5157
5158         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5159 }
5160
5161 /*
5162  * [7] 9.4.21
5163  */
5164 static void
5165 dtap_gmm_service_acc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5166 {
5167         guint32 curr_offset;
5168         guint32 consumed;
5169         guint   curr_len;
5170
5171         curr_offset = offset;
5172         curr_len = len;
5173
5174         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_SENT;
5175
5176         ELEM_OPT_TLV( 0x32 , GSM_A_PDU_TYPE_GM, DE_PDP_CONTEXT_STAT , NULL);
5177
5178         /* MBMS context status 10.5.7.6 TLV 2 - 18 */
5179         ELEM_OPT_TLV( 0x35 , GSM_A_PDU_TYPE_GM, DE_MBMS_CTX_STATUS , NULL);
5180
5181         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5182 }
5183
5184 /*
5185  * [7] 9.4.22
5186  */
5187 static void
5188 dtap_gmm_service_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5189 {
5190         guint32 curr_offset;
5191         guint32 consumed;
5192         guint   curr_len;
5193
5194         curr_offset = offset;
5195         curr_len = len;
5196
5197         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_SENT;
5198
5199         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_GMM_CAUSE );
5200
5201         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5202 }
5203
5204 /*
5205  * [8] 9.5.1 Activate PDP context request
5206  */
5207 static void
5208 dtap_sm_act_pdp_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5209 {
5210         guint32 curr_offset;
5211         guint32 consumed;
5212         guint   curr_len;
5213
5214         curr_offset = offset;
5215         curr_len = len;
5216
5217         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
5218
5219         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_NET_SAPI );
5220
5221         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_LLC_SAPI );
5222
5223         ELEM_MAND_LV(GSM_A_PDU_TYPE_GM, DE_QOS , " - Requested QoS" );
5224
5225         ELEM_MAND_LV(GSM_A_PDU_TYPE_GM, DE_PD_PRO_ADDR , " - Requested PDP address" );
5226
5227         ELEM_OPT_TLV( 0x28 , GSM_A_PDU_TYPE_GM, DE_ACC_POINT_NAME , NULL);
5228
5229         ELEM_OPT_TLV( 0x27 , GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT , NULL);
5230
5231         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5232 }
5233
5234 /*
5235  * [8] 9.5.2 Activate PDP context accept
5236  */
5237 static void
5238 dtap_sm_act_pdp_acc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5239 {
5240         guint32 curr_offset;
5241         guint32 consumed;
5242         guint   curr_len;
5243
5244         curr_offset = offset;
5245         curr_len = len;
5246
5247         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
5248
5249         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_LLC_SAPI );
5250
5251         ELEM_MAND_LV(GSM_A_PDU_TYPE_GM, DE_QOS , " - Negotiated QoS" );
5252
5253 #if 0
5254         /* This is done automatically */
5255         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_SPARE );
5256         curr_offset--;
5257         curr_len++;
5258 #endif
5259
5260         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_RAD_PRIO );
5261
5262         ELEM_OPT_TLV( 0x2B , GSM_A_PDU_TYPE_GM, DE_PD_PRO_ADDR , NULL);
5263
5264         ELEM_OPT_TLV( 0x27 , GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT , NULL);
5265
5266         ELEM_OPT_TLV( 0x34 , GSM_A_PDU_TYPE_GM, DE_PACKET_FLOW_ID , NULL);
5267
5268         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5269 }
5270
5271 /*
5272  * [8] 9.5.3 Activate PDP context reject
5273  */
5274 static void
5275 dtap_sm_act_pdp_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5276 {
5277         guint32 curr_offset;
5278         guint32 consumed;
5279         guint   curr_len;
5280
5281         curr_offset = offset;
5282         curr_len = len;
5283
5284         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
5285
5286         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_SM_CAUSE );
5287
5288         ELEM_OPT_TLV( 0x27 , GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT , NULL);
5289
5290         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5291 }
5292
5293 /*
5294  * [8] 9.5.4 Activate Secondary PDP Context Request
5295  */
5296 static void
5297 dtap_sm_act_sec_pdp_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5298 {
5299         guint32 curr_offset;
5300         guint32 consumed;
5301         guint   curr_len;
5302
5303         curr_offset = offset;
5304         curr_len = len;
5305
5306         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
5307
5308         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_NET_SAPI );
5309
5310         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_LLC_SAPI );
5311
5312         ELEM_MAND_LV(GSM_A_PDU_TYPE_GM, DE_QOS , " - Requested QoS" );
5313
5314         ELEM_MAND_LV(GSM_A_PDU_TYPE_GM, DE_LINKED_TI , NULL);
5315
5316         /* 3GPP TS 24.008 version 6.8.0 Release 6, 36 TFT Traffic Flow Template 10.5.6.12 O TLV 3-257 */
5317         ELEM_OPT_TLV( 0x36 , GSM_A_PDU_TYPE_GM, DE_TRAFFIC_FLOW_TEMPLATE , NULL);
5318
5319         ELEM_OPT_TLV( 0x27 , GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT , NULL);
5320
5321         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5322 }
5323
5324 /*
5325  * [7] 9.5.5
5326  */
5327 static void
5328 dtap_sm_act_sec_pdp_acc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5329 {
5330         guint32 curr_offset;
5331         guint32 consumed;
5332         guint   curr_len;
5333
5334         curr_offset = offset;
5335         curr_len = len;
5336
5337         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
5338
5339         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_LLC_SAPI );
5340
5341         ELEM_MAND_LV(GSM_A_PDU_TYPE_GM, DE_QOS , " - Negotiated QoS" );
5342
5343         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_RAD_PRIO);
5344
5345 #if 0
5346         /* This is done automatically */
5347         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_SPARE );
5348         curr_offset--;
5349         curr_len++;
5350 #endif
5351
5352         ELEM_OPT_TLV( 0x34 , GSM_A_PDU_TYPE_GM, DE_PACKET_FLOW_ID , NULL);
5353
5354         ELEM_OPT_TLV( 0x27 , GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT , NULL);
5355
5356         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5357 }
5358
5359 /*
5360  * [8] 9.5.6 Activate Secondary PDP Context Reject
5361  */
5362 static void
5363 dtap_sm_act_sec_pdp_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5364 {
5365         guint32 curr_offset;
5366         guint32 consumed;
5367         guint   curr_len;
5368
5369         curr_offset = offset;
5370         curr_len = len;
5371
5372         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
5373
5374         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_SM_CAUSE );
5375
5376         ELEM_OPT_TLV( 0x27 , GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT , NULL);
5377
5378         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5379 }
5380
5381 /*
5382  * [8] 9.5.7 Request PDP context activation
5383  */
5384 static void
5385 dtap_sm_req_pdp_act(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5386 {
5387         guint32 curr_offset;
5388         guint32 consumed;
5389         guint   curr_len;
5390
5391         curr_offset = offset;
5392         curr_len = len;
5393
5394         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
5395
5396         ELEM_MAND_LV(GSM_A_PDU_TYPE_GM, DE_PD_PRO_ADDR , " - Offered PDP address" );
5397
5398         ELEM_OPT_TLV( 0x28 , GSM_A_PDU_TYPE_GM, DE_ACC_POINT_NAME , NULL);
5399
5400         ELEM_OPT_TLV( 0x27 , GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT , NULL);
5401
5402         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5403 }
5404
5405 /*
5406  * [8] 9.5.8 Request PDP context activation reject
5407  */
5408 static void
5409 dtap_sm_req_pdp_act_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5410 {
5411         guint32 curr_offset;
5412         guint32 consumed;
5413         guint   curr_len;
5414
5415         curr_offset = offset;
5416         curr_len = len;
5417
5418         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
5419
5420         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_SM_CAUSE );
5421
5422         ELEM_OPT_TLV( 0x27 , GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT , NULL);
5423
5424         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5425 }
5426
5427 /*
5428  * [8] 9.5.9 Modify PDP context request (Network to MS direction)
5429  */
5430 static void
5431 dtap_sm_mod_pdp_req_net(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5432 {
5433         guint32 curr_offset;
5434         guint32 consumed;
5435         guint   curr_len;
5436
5437         curr_offset = offset;
5438         curr_len = len;
5439
5440         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
5441
5442         ELEM_MAND_V(GSM_A_PDU_TYPE_GM,DE_RAD_PRIO);
5443 #if 0
5444         /* This is done automatically */
5445         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_SPARE );
5446         curr_offset--;
5447         curr_len++;
5448 #endif
5449
5450         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_LLC_SAPI );
5451
5452         ELEM_MAND_LV(GSM_A_PDU_TYPE_GM, DE_QOS , " - New QoS" );
5453
5454         ELEM_OPT_TLV( 0x2B , GSM_A_PDU_TYPE_GM, DE_PD_PRO_ADDR , NULL);
5455
5456         ELEM_OPT_TLV( 0x34 , GSM_A_PDU_TYPE_GM, DE_PACKET_FLOW_ID , NULL);
5457
5458         ELEM_OPT_TLV( 0x27 , GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT , NULL);
5459
5460         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5461 }
5462
5463 /*
5464  * [8] 9.5.10 Modify PDP context request (MS to network direction)
5465  */
5466 static void
5467 dtap_sm_mod_pdp_req_ms(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5468 {
5469         guint32 curr_offset;
5470         guint32 consumed;
5471         guint   curr_len;
5472
5473         curr_offset = offset;
5474         curr_len = len;
5475
5476         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
5477
5478         ELEM_OPT_TV( 0x32 , GSM_A_PDU_TYPE_GM, DE_LLC_SAPI , " - Requested LLC SAPI" );
5479
5480         ELEM_OPT_TLV( 0x30 , GSM_A_PDU_TYPE_GM, DE_QOS , " - Requested new QoS" );
5481
5482         ELEM_OPT_TLV( 0x31 , GSM_A_PDU_TYPE_GM, DE_TRAFFIC_FLOW_TEMPLATE , " - New TFT" );
5483
5484         ELEM_OPT_TLV( 0x27 , GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT , NULL);
5485
5486         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5487 }
5488
5489 /*
5490  * [8] 9.5.11 Modify PDP context accept (MS to network direction)
5491  */
5492 static void
5493 dtap_sm_mod_pdp_acc_ms(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5494 {
5495         guint32 curr_offset;
5496         guint32 consumed;
5497         guint   curr_len;
5498
5499         curr_offset = offset;
5500         curr_len = len;
5501
5502         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
5503
5504         ELEM_OPT_TLV( 0x27 , GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT , NULL);
5505
5506         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5507 }
5508
5509 /*
5510  * [8] 9.5.12 Modify PDP context accept (Network to MS direction)
5511  */
5512 static void
5513 dtap_sm_mod_pdp_acc_net(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5514 {
5515         guint32 curr_offset;
5516         guint32 consumed;
5517         guint   curr_len;
5518
5519         curr_offset = offset;
5520         curr_len = len;
5521
5522         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
5523
5524         ELEM_OPT_TLV( 0x30 , GSM_A_PDU_TYPE_GM, DE_QOS , " - Negotiated QoS" );
5525
5526         ELEM_OPT_TV( 0x32 , GSM_A_PDU_TYPE_GM, DE_LLC_SAPI , " - Negotiated LLC SAPI" );
5527
5528         ELEM_OPT_TV_SHORT ( 0x80 , GSM_A_PDU_TYPE_GM , DE_RAD_PRIO , " - New radio priority" );
5529
5530         ELEM_OPT_TLV( 0x34 , GSM_A_PDU_TYPE_GM, DE_PACKET_FLOW_ID , NULL);
5531
5532         ELEM_OPT_TLV( 0x27 , GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT , NULL);
5533
5534         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5535 }
5536
5537 /*
5538  * [8] 9.5.13 Modify PDP Context Reject
5539  */
5540 static void
5541 dtap_sm_mod_pdp_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5542 {
5543         guint32 curr_offset;
5544         guint32 consumed;
5545         guint   curr_len;
5546
5547         curr_offset = offset;
5548         curr_len = len;
5549
5550         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
5551
5552         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_SM_CAUSE );
5553
5554         ELEM_OPT_TLV( 0x27 , GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT , NULL);
5555
5556         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5557 }
5558
5559 /*
5560  * [8] 9.5.14 Deactivate PDP context request
5561  */
5562 static void
5563 dtap_sm_deact_pdp_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5564 {
5565         guint32 curr_offset;
5566         guint32 consumed;
5567         guint   curr_len;
5568
5569         curr_offset = offset;
5570         curr_len = len;
5571
5572         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
5573
5574         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_SM_CAUSE );
5575
5576         ELEM_OPT_TV_SHORT( 0x90 , GSM_A_PDU_TYPE_GM , DE_TEAR_DOWN_IND , NULL);
5577
5578         ELEM_OPT_TLV( 0x27 , GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT , NULL);
5579
5580         /* MBMS context status 10.5.7.6 TLV 2 - 18 */
5581         ELEM_OPT_TLV( 0x35 , GSM_A_PDU_TYPE_GM, DE_MBMS_CTX_STATUS , NULL);
5582
5583         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5584 }
5585
5586 /*
5587  * [8] 9.5.15 Deactivate PDP context accept
5588  */
5589 static void
5590 dtap_sm_deact_pdp_acc(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5591 {
5592         guint32 curr_offset;
5593         guint32 consumed;
5594         guint   curr_len;
5595
5596         curr_offset = offset;
5597         curr_len = len;
5598
5599         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
5600
5601         ELEM_OPT_TLV( 0x27 , GSM_A_PDU_TYPE_GM, DE_PRO_CONF_OPT , NULL);
5602
5603         /* MBMS context status 10.5.7.6 TLV 2 - 18 */
5604         ELEM_OPT_TLV( 0x35 , GSM_A_PDU_TYPE_GM, DE_MBMS_CTX_STATUS , NULL);
5605
5606         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5607 }
5608
5609 /*
5610  * [8] 9.5.21 SM Status
5611  */
5612 static void
5613 dtap_sm_status(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
5614 {
5615         guint32 curr_offset;
5616         guint32 consumed;
5617         guint   curr_len;
5618
5619         curr_offset = offset;
5620         curr_len = len;
5621
5622         gsm_a_dtap_pinfo->p2p_dir = P2P_DIR_UNKNOWN;
5623
5624         ELEM_MAND_V(GSM_A_PDU_TYPE_GM, DE_SM_CAUSE );
5625
5626         EXTRANEOUS_DATA_CHECK(curr_len, 0);
5627 }
5628
5629 /*
5630  * [8] 9.5.22 Activate MBMS Context Request
5631  */
5632
5633         /* Requested MBMS NSAPI Enhanced Network service access point identifier 10.5.6.15 M V */
5634         /* Requested LLC SAPI LLC service access point identifier 10.5.6.9 M V 1 */
5635         /* Supported MBMS bearer capabilities MBMS bearer capabilities 10.5.6.14 M LV 2 - 3 */
5636         /* Requested multicast address Packet data protocol address 10.5.6.4 M LV 3 - 19 */
5637         /* Access point name Access point name 10.5.6.1 M LV 2 - 101 */
5638         /* 35 MBMS protocol configuration options MBMS protocol configuration options 10.5.6.15 O TLV 3 - 253 */
5639
5640 /*
5641  * [8] 9.5.23 Activate MBMS Context Accept
5642  */
5643
5644 /*
5645  * [8] 9.5.24 Activate MBMS Context Reject
5646  */
5647
5648 /*
5649  * [8] 9.5.25 Request MBMS Context Activation
5650  */
5651
5652 /*
5653  * [8] 9.5.26 Request MBMS Context Activation Reject
5654  */
5655
5656 #define NUM_GSM_DTAP_MSG_GMM (sizeof(gsm_a_dtap_msg_gmm_strings)/sizeof(value_string))
5657 static gint ett_gsm_dtap_msg_gmm[NUM_GSM_DTAP_MSG_GMM];
5658 static void (*dtap_msg_gmm_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
5659         dtap_gmm_attach_req,            /* Attach Request */
5660         dtap_gmm_attach_acc,            /* Attach Accept */
5661         dtap_gmm_attach_com,            /* Attach Complete */
5662         dtap_gmm_attach_rej,            /* Attach Reject */
5663         dtap_gmm_detach_req,            /* Detach Request */
5664         dtap_gmm_detach_acc,            /* Detach Accept */
5665         dtap_gmm_rau_req,                       /* Routing Area Update Request */
5666         dtap_gmm_rau_acc,                       /* Routing Area Update Accept */
5667         dtap_gmm_rau_com,                       /* Routing Area Update Complete */
5668         dtap_gmm_rau_rej,                       /* Routing Area Update Reject */
5669         dtap_gmm_service_req,           /* Service Request */
5670         dtap_gmm_service_acc,           /* Service Accept */
5671         dtap_gmm_service_rej,           /* Service Reject */
5672         dtap_gmm_ptmsi_realloc_cmd,     /* P-TMSI Reallocation Command */
5673         dtap_gmm_ptmsi_realloc_com,     /* P-TMSI Reallocation Complete */
5674         dtap_gmm_auth_ciph_req,         /* Authentication and Ciphering Req */
5675         dtap_gmm_auth_ciph_resp,        /* Authentication and Ciphering Resp */
5676         dtap_gmm_auth_ciph_rej,         /* Authentication and Ciphering Rej */
5677         dtap_gmm_auth_ciph_fail,        /* Authentication and Ciphering Failure */
5678         dtap_gmm_ident_req,                     /* Identity Request */
5679         dtap_gmm_ident_res,                     /* Identity Response */
5680         dtap_gmm_status,                        /* GMM Status */
5681         dtap_gmm_information,           /* GMM Information */
5682         NULL,   /* NONE */
5683 };
5684
5685 #define NUM_GSM_DTAP_MSG_SM (sizeof(gsm_a_dtap_msg_sm_strings)/sizeof(value_string))
5686 static gint ett_gsm_dtap_msg_sm[NUM_GSM_DTAP_MSG_SM];
5687 static void (*dtap_msg_sm_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
5688         dtap_sm_act_pdp_req,            /* Activate PDP Context Request */
5689         dtap_sm_act_pdp_acc,            /* Activate PDP Context Accept */
5690         dtap_sm_act_pdp_rej,            /* Activate PDP Context Reject */
5691         dtap_sm_req_pdp_act,            /* Request PDP Context Activation */
5692         dtap_sm_req_pdp_act_rej,        /* Request PDP Context Activation rej. */
5693         dtap_sm_deact_pdp_req,          /* Deactivate PDP Context Request */
5694         dtap_sm_deact_pdp_acc,          /* Deactivate PDP Context Accept */
5695         dtap_sm_mod_pdp_req_net,        /* Modify PDP Context Request(Network to MS direction) */
5696         dtap_sm_mod_pdp_acc_ms,         /* Modify PDP Context Accept (MS to network direction) */
5697         dtap_sm_mod_pdp_req_ms,         /* Modify PDP Context Request(MS to network direction) */
5698         dtap_sm_mod_pdp_acc_net,        /* Modify PDP Context Accept (Network to MS direction) */
5699         dtap_sm_mod_pdp_rej,            /* Modify PDP Context Reject */
5700         dtap_sm_act_sec_pdp_req,        /* Activate Secondary PDP Context Request */
5701         dtap_sm_act_sec_pdp_acc,        /* Activate Secondary PDP Context Accept */
5702         dtap_sm_act_sec_pdp_rej,        /* Activate Secondary PDP Context Reject */
5703         NULL,                                           /* Reserved: was allocated in earlier phases of the protocol */
5704         NULL,                                           /* Reserved: was allocated in earlier phases of the protocol */
5705         NULL,                                           /* Reserved: was allocated in earlier phases of the protocol */
5706         NULL,                                           /* Reserved: was allocated in earlier phases of the protocol */
5707         NULL,                                           /* Reserved: was allocated in earlier phases of the protocol */
5708         dtap_sm_status,                         /* SM Status */
5709                                                                 /* Activate MBMS Context Request */
5710                                                                 /* Activate MBMS Context Accept */
5711                                                                 /* Activate MBMS Context Reject */
5712                                                                 /* Request MBMS Context Activation */
5713                                                                 /* Request MBMS Context Activation Reject */
5714         NULL,   /* NONE */
5715 };
5716
5717 void get_gmm_msg_params(guint8 oct, const gchar **msg_str, int *ett_tree, int *hf_idx, msg_fcn *msg_fcn)
5718 {
5719         gint                    idx;
5720
5721         *msg_str = match_strval_idx((guint32) (oct & DTAP_GMM_IEI_MASK), gsm_a_dtap_msg_gmm_strings, &idx);
5722         *ett_tree = ett_gsm_dtap_msg_gmm[idx];
5723         *hf_idx = hf_gsm_a_dtap_msg_gmm_type;
5724         *msg_fcn = dtap_msg_gmm_fcn[idx];
5725
5726         return;
5727 }
5728
5729 void get_sm_msg_params(guint8 oct, const gchar **msg_str, int *ett_tree, int *hf_idx, msg_fcn *msg_fcn)
5730 {
5731         gint                    idx;
5732
5733         *msg_str = match_strval_idx((guint32) (oct & DTAP_SM_IEI_MASK), gsm_a_dtap_msg_sm_strings, &idx);
5734         *ett_tree = ett_gsm_dtap_msg_sm[idx];
5735         *hf_idx = hf_gsm_a_dtap_msg_sm_type;
5736         *msg_fcn = dtap_msg_sm_fcn[idx];
5737
5738         return;
5739 }
5740
5741 /* Register the protocol with Wireshark */
5742 void
5743 proto_register_gsm_a_gm(void)
5744 {
5745         guint           i;
5746         guint           last_offset;
5747
5748         /* Setup list of header fields */
5749
5750         static hf_register_info hf[] =
5751         {
5752         { &hf_gsm_a_dtap_msg_gmm_type,
5753                 { "DTAP GPRS Mobility Management Message Type", "gsm_a.dtap_msg_gmm_type",
5754                   FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_gmm_strings), 0x0,
5755                   NULL, HFILL }
5756         },
5757         { &hf_gsm_a_dtap_msg_sm_type,
5758                 { "DTAP GPRS Session Management Message Type",  "gsm_a.dtap_msg_sm_type",
5759                   FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_sm_strings), 0x0,
5760                   NULL, HFILL }
5761         },
5762         { &hf_gsm_a_gm_elem_id,
5763                 { "Element ID", "gsm_a_gm.elem_id",
5764                 FT_UINT8, BASE_DEC, NULL, 0,
5765                 NULL, HFILL }
5766         },
5767         { &hf_gsm_a_qos_delay_cls,
5768                 { "Quality of Service Delay class", "gsm_a.qos.delay_cls",
5769                   FT_UINT8, BASE_DEC, VALS(gsm_a_qos_delay_cls_vals), 0x38,
5770                   NULL, HFILL }
5771         },
5772         { &hf_gsm_a_qos_qos_reliability_cls,
5773                 { "Reliability class", "gsm_a.qos.delay_cls",
5774                   FT_UINT8, BASE_DEC, VALS(gsm_a_qos_delay_cls_vals), 0x07,
5775                   NULL, HFILL }
5776         },
5777         { &hf_gsm_a_qos_traffic_cls,
5778                 { "Traffic class", "gsm_a.qos.traffic_cls",
5779                   FT_UINT8, BASE_DEC, VALS(gsm_a_qos_traffic_cls_vals), 0xe0,
5780                   NULL, HFILL }
5781         },
5782         { &hf_gsm_a_qos_del_order,
5783                 { "Delivery order", "gsm_a.qos.del_order",
5784                   FT_UINT8, BASE_DEC, VALS(gsm_a_qos_traffic_cls_vals), 0x18,
5785                   NULL, HFILL }
5786         },
5787         { &hf_gsm_a_qos_del_of_err_sdu,
5788                 { "Delivery of erroneous SDUs", "gsm_a.qos.del_of_err_sdu",
5789                   FT_UINT8, BASE_DEC, VALS(gsm_a_qos_del_of_err_sdu_vals), 0x03,
5790                   NULL, HFILL }
5791         },
5792         { &hf_gsm_a_qos_ber,
5793                 { "Residual Bit Error Rate (BER)", "gsm_a.qos.ber",
5794                   FT_UINT8, BASE_DEC, VALS(gsm_a_qos_ber_vals), 0xf0,
5795                   NULL, HFILL }
5796         },
5797         { &hf_gsm_a_qos_sdu_err_rat,
5798                 { "SDU error ratio", "gsm_a.qos.sdu_err_rat",
5799                   FT_UINT8, BASE_DEC, VALS(gsm_a_qos_sdu_err_rat_vals), 0x0f,
5800                   NULL, HFILL }
5801         },
5802         { &hf_gsm_a_qos_traff_hdl_pri,
5803                 { "Traffic handling priority", "gsm_a.qos.traff_hdl_pri",
5804                   FT_UINT8, BASE_DEC, VALS(gsm_a_qos_traff_hdl_pri_vals), 0x03,
5805                   NULL, HFILL }
5806         },
5807         { &hf_gsm_a_gmm_split_on_ccch,
5808                 { "SPLIT on CCCH","gsm_a.gmm.split_on_ccch",
5809                   FT_BOOLEAN, 8, TFS(&gsm_a_gmm_split_on_ccch_value), 0x08,
5810                   NULL, HFILL }
5811         },
5812         { &hf_gsm_a_gmm_non_drx_timer,
5813                 { "Non-DRX timer","gsm_a.gmm.non_drx_timer",
5814                   FT_UINT8, BASE_DEC, VALS(gsm_a_gmm_non_drx_timer_strings), 0x07,
5815                   NULL, HFILL }
5816         },
5817         { &hf_gsm_a_gmm_cn_spec_drs_cycle_len_coef,
5818                 { "CN Specific DRX cycle length coefficient","gsm_a.gmm.cn_spec_drs_cycle_len_coef",
5819                   FT_UINT8, BASE_DEC, VALS(gsm_a_gmm_cn_spec_drs_cycle_len_coef_strings), 0xf0,
5820                   NULL, HFILL }
5821         },
5822         { &hf_gsm_a_tft_op_code,
5823                 { "TFT operation code", "gsm_a.tft.op_code",
5824                   FT_UINT8, BASE_DEC, VALS(gsm_a_tft_op_code_vals), 0xe0,
5825                   NULL, HFILL }
5826         },
5827         { &hf_gsm_a_tft_e_bit,
5828                 { "E bit","gsm_a.tft.e_bit",
5829                   FT_BOOLEAN, 8, TFS(&gsm_a_tft_e_bit), 0x10,
5830                   NULL, HFILL }
5831         },
5832         { &hf_gsm_a_tft_pkt_flt,
5833                 { "Number of packet filters", "gsm_a.tft.pkt_flt",
5834                   FT_UINT8, BASE_DEC, NULL, 0x0f,
5835                   NULL, HFILL }
5836         },
5837         { &hf_gsm_a_tft_ip4_address,
5838                 { "IPv4 adress", "gsm_a.tft.ip4_address",
5839                   FT_IPv4, BASE_NONE, NULL, 0x0,
5840                 NULL, HFILL }
5841         },
5842         { &hf_gsm_a_tft_ip4_mask,
5843                 { "IPv4 address mask", "gsm_a.tft.ip4_mask",
5844                   FT_IPv4, BASE_NONE, NULL, 0x0,
5845                 NULL, HFILL }
5846         },
5847         { &hf_gsm_a_tft_ip6_address,
5848                 { "IPv6 adress", "gsm_a.tft.ip6_address",
5849                   FT_IPv6, BASE_NONE, NULL, 0x0,
5850                 NULL, HFILL }
5851         },
5852         { &hf_gsm_a_tft_ip6_mask,
5853                 { "IPv6 adress mask", "gsm_a.tft.ip6_mask",
5854                   FT_IPv6, BASE_NONE, NULL, 0x0,
5855                 NULL, HFILL }
5856         },
5857         { &hf_gsm_a_tft_protocol_header,
5858                 { "Protocol/header", "gsm_a.tft.protocol_header",
5859                   FT_UINT8, BASE_HEX, NULL, 0x0,
5860                 NULL, HFILL }
5861         },
5862         { &hf_gsm_a_tft_port,
5863                 { "Port", "gsm_a.tft.port", 
5864                   FT_UINT16, BASE_DEC, NULL, 0x0,
5865                 NULL, HFILL }
5866         },
5867         { &hf_gsm_a_tft_port_low,
5868                 { "Low limit port", "gsm_a.tft.port_low",
5869                   FT_UINT16, BASE_DEC, NULL, 0x0,
5870                 NULL, HFILL }
5871         },
5872         { &hf_gsm_a_tft_port_high,
5873                 { "High limit port", "gsm_a.tft.port_high",
5874                   FT_UINT16, BASE_DEC, NULL, 0x0,
5875                 NULL, HFILL }
5876         },
5877         { &hf_gsm_a_tft_security,
5878                 { "IPSec security parameter index", "gsm_a.tft.security",
5879                   FT_UINT32, BASE_HEX, NULL, 0x0,
5880                 NULL, HFILL }
5881         },
5882         { &hf_gsm_a_tft_traffic_mask,
5883                 { "Mask field", "gsm_a.tft.traffic_mask",
5884                   FT_UINT8, BASE_HEX, NULL, 0x0,
5885                 NULL, HFILL }
5886         },
5887         { &hf_gsm_a_ptmsi_sig,
5888                 { "P-TMSI Signature", "gsm_a.ptmsi_sig",
5889                   FT_UINT24, BASE_HEX, NULL, 0x0,
5890                 NULL, HFILL }
5891         },
5892         { &hf_gsm_a_ptmsi_sig2,
5893                 { "P-TMSI Signature 2", "gsm_a.ptmsi_sig2",
5894                   FT_UINT24, BASE_HEX, NULL, 0x0,
5895                 NULL, HFILL }
5896         },
5897         { &hf_gsm_a_gm_acc_tech_type,
5898                 { "Access Technology Type", "gsm_a.gm.acc_tech_type",
5899                   FT_UINT8, BASE_DEC, VALS(gsm_a_gm_acc_tech_type_vals), 0x0,
5900                 NULL, HFILL }
5901         },
5902         { &hf_gsm_a_gm_acc_cap_struct_len,
5903                 { "Length in bits", "gsm_a.gm.acc_cap_struct_len",
5904                   FT_UINT8, BASE_HEX_DEC,NULL, 0x0,
5905                 NULL, HFILL }
5906         },
5907         { &hf_gsm_a_gm_sms_value,
5908                 { "SMS_VALUE (Switch-Measure-Switch)", "gsm_a.gm.sms",
5909                   FT_UINT8, BASE_DEC, VALS(gsm_a_gm_sm_vals), 0x0,
5910                 NULL, HFILL }
5911         },
5912         { &hf_gsm_a_gm_sm_value,
5913                 { "(SM_VALUE) Switch-Measure", "gsm_a.gm.sm",
5914                   FT_UINT8, BASE_DEC, VALS(gsm_a_gm_sm_vals), 0x0,
5915                 NULL, HFILL }
5916         },
5917         { &hf_gsm_a_gm_sm_ext,
5918                 { "Ext", "gsm_a.gm.sm.ext",
5919                   FT_UINT8, BASE_HEX, NULL, 0x80,
5920                 NULL, HFILL }
5921         },
5922         { &hf_gsm_a_gm_cause,
5923                 { "gmm Cause", "gsm_a.gm.cause",
5924                   FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(gmm_cause_vals), 0x0,
5925                 NULL, HFILL }
5926         },
5927         { &hf_gsm_a_gm_fop,
5928                 { "Follow-on proceed", "gsm_a.gm.fop",
5929                 FT_BOOLEAN, 8, NULL, 0x08,
5930                 NULL, HFILL }
5931         },
5932         { &hf_gsm_a_gm_res_of_attach,
5933                 { "Result of attach", "gsm_a.gm.res_of_attach",
5934                 FT_UINT8, BASE_DEC, VALS(gsm_a_gm_res_of_attach_vals), 0x07,
5935                 NULL, HFILL }
5936         },
5937         { &hf_gsm_a_gm_type_of_ciph_alg,
5938                 { "Type of ciphering algorithm", "gsm_a.gm.type_of_ciph_alg",
5939                 FT_UINT8, BASE_DEC, VALS(gsm_a_gm_type_of_ciph_alg_vals), 0x07,
5940                 NULL, HFILL }
5941         },
5942         { &hf_gsm_a_gm_imeisv_req,
5943                 { "IMEISV request", "gsm_a.gm.imeisv_req",
5944                 FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(gsm_a_gm_imeisv_req_vals), 0x00,
5945                 NULL, HFILL }
5946         },
5947         { &hf_gsm_a_gm_ac_ref_nr,
5948                 { "A&C reference number", "gsm_a.gm.ac_ref_nr",
5949                   FT_UINT8, BASE_DEC, NULL, 0x0,
5950                 NULL, HFILL }
5951         },
5952         { &hf_gsm_a_gm_force_to_standby,
5953                 { "Force to standby", "gsm_a.gm.force_to_standby",
5954                 FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(gsm_a_gm_force_to_standby_vals), 0x00,
5955                 NULL, HFILL }
5956         },
5957         { &hf_gsm_a_gm_ciph_key_seq_num,
5958                 { "Ciphering key sequence number", "gsm_a.gm.ciph_key_seq_num",
5959                 FT_UINT8, BASE_DEC, NULL, 0x00,
5960                 NULL, HFILL }
5961         },
5962         { &hf_gsm_a_gm_serv_type,
5963                 { "Service type", "gsm_a.gm.serv_type",
5964                 FT_UINT8, BASE_DEC, VALS(gsm_a_gm_serv_type_vals), 0x00,
5965                 NULL, HFILL }
5966         },
5967         { &hf_gsm_a_gm_for,
5968                 { "Follow-on request pending", "gsm_a.gm.for",
5969                 FT_BOOLEAN, 8, NULL, 0x08,
5970                 NULL, HFILL }
5971         },
5972         { &hf_gsm_a_gm_type_of_attach,
5973                 { "Type of attach", "gsm_a.gm.type_of_attach",
5974                 FT_UINT8, BASE_DEC, VALS(gsm_a_gm_type_of_attach_vals), 0x07,
5975                 NULL, HFILL }
5976         },
5977         { &hf_gsm_a_gm_tmsi_flag,
5978                 { "TMSI flag", "gsm_a.gm.tmsi_flag",
5979                 FT_BOOLEAN, 8, TFS(&gsm_a_gm_tmsi_flag_value), 0x01,
5980                 NULL, HFILL }
5981         },
5982         { &hf_gsm_a_gm_update_type,
5983                 { "Update type", "gsm_a.gm.update_type",
5984                 FT_UINT8, BASE_DEC, VALS(gsm_a_gm_update_type_vals), 0x07,
5985                 NULL, HFILL }
5986         },
5987         };
5988
5989         /* Setup protocol subtree array */
5990 #define NUM_INDIVIDUAL_ELEMS    15
5991         gint *ett[NUM_INDIVIDUAL_ELEMS +
5992                   NUM_GSM_DTAP_MSG_GMM + NUM_GSM_DTAP_MSG_SM +
5993                   NUM_GSM_GM_ELEM];
5994
5995         ett[0]  = &ett_tc_component;
5996         ett[1]  = &ett_tc_invoke_id;
5997         ett[2]  = &ett_tc_linked_id;
5998         ett[3]  = &ett_tc_opr_code;
5999         ett[4]  = &ett_tc_err_code;
6000         ett[5]  = &ett_tc_prob_code;
6001         ett[6]  = &ett_tc_sequence;
6002         ett[7]  = &ett_gmm_drx;
6003         ett[8]  = &ett_gmm_detach_type;
6004         ett[9]  = &ett_gmm_attach_type;
6005         ett[10] = &ett_gmm_context_stat;
6006         ett[11] = &ett_gmm_update_type;
6007         ett[12] = &ett_gmm_radio_cap;
6008         ett[13] = &ett_gmm_rai;
6009         ett[14] = &ett_sm_tft;
6010
6011         last_offset = NUM_INDIVIDUAL_ELEMS;
6012
6013         for (i=0; i < NUM_GSM_DTAP_MSG_GMM; i++, last_offset++)
6014         {
6015                 ett_gsm_dtap_msg_gmm[i] = -1;
6016                 ett[last_offset] = &ett_gsm_dtap_msg_gmm[i];
6017         }
6018
6019         for (i=0; i < NUM_GSM_DTAP_MSG_SM; i++, last_offset++)
6020         {
6021                 ett_gsm_dtap_msg_sm[i] = -1;
6022                 ett[last_offset] = &ett_gsm_dtap_msg_sm[i];
6023         }
6024
6025         for (i=0; i < NUM_GSM_GM_ELEM; i++, last_offset++)
6026         {
6027                 ett_gsm_gm_elem[i] = -1;
6028                 ett[last_offset] = &ett_gsm_gm_elem[i];
6029         }
6030
6031         proto_a_gm =
6032                 proto_register_protocol("GSM A-I/F GPRS Mobility and Session Management", "GSM Management", "gsm_a_gm");
6033
6034         proto_register_field_array(proto_a_gm, hf, array_length(hf));
6035
6036         proto_register_subtree_array(ett, array_length(ett));
6037
6038         /* subdissector code */
6039         gprs_sm_pco_subdissector_table = register_dissector_table("sm_pco.protocol",
6040                 "GPRS SM PCO PPP protocol", FT_UINT16, BASE_HEX);
6041 }
6042
6043 void
6044 proto_reg_handoff_gsm_a_gm(void)
6045 {
6046         data_handle = find_dissector("data");
6047         rrc_irat_ho_info_handle = find_dissector("rrc.irat.irat_ho_info");
6048 }