Get rid of check_col, while at it set ENC.
[metze/wireshark/wip.git] / epan / dissectors / packet-bssap.c
1 /* packet-bssap.c
2  * Routines for Base Station Subsystem Application Part (BSSAP/BSAP) dissection
3  * Specifications from 3GPP2 (www.3gpp2.org) and 3GPP (www.3gpp.org)
4  *  IOS 4.0.1 (BSAP)
5  *  GSM 08.06 (BSSAP)
6  *
7  * Copyright 2003, Michael Lum <mlum [AT] telostech.com>
8  * In association with Telos Technology Inc.
9  *
10  * Added BSSAP+ according to ETSI TS 129 018 V6.3.0 (2005-3GPP TS 29.018 version 6.3.0 Release 6)
11  * Copyright 2006, Anders Broman <Anders.Broman [AT] ericsson.com>
12  *
13  * $Id$
14  *
15  * Wireshark - Network traffic analyzer
16  * By Gerald Combs <gerald@wireshark.org>
17  * Copyright 1998 Gerald Combs
18  *
19  * This program is free software; you can redistribute it and/or
20  * modify it under the terms of the GNU General Public License
21  * as published by the Free Software Foundation; either version 2
22  * of the License, or (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program; if not, write to the Free Software
31  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32  */
33
34 #ifdef HAVE_CONFIG_H
35 # include "config.h"
36 #endif
37
38 #include <glib.h>
39
40 #ifdef HAVE_SYS_TYPES_H
41 # include <sys/types.h>
42 #endif
43
44 #ifdef HAVE_NETINET_IN_H
45 # include <netinet/in.h>
46 #endif
47
48 #include <epan/packet.h>
49 #include <epan/prefs.h>
50 #include <epan/emem.h>
51
52 #include "packet-bssap.h"
53 #include "packet-sccp.h"
54 #include "packet-gsm_a_common.h"
55 #include "packet-e212.h"
56
57 void proto_reg_handoff_bssap(void);
58
59 #define BSSAP 0
60 #define BSAP  1
61
62 #define GSM_INTERFACE 0
63 #define LB_INTERFACE  1
64
65 #define BSSAP_OR_BSAP_DEFAULT BSSAP
66
67 #define GSM_OR_LB_INTERFACE_DEFAULT GSM_INTERFACE
68
69 #define PDU_TYPE_OFFSET 0
70 #define PDU_TYPE_LENGTH 1
71
72 /* Same as below but with names typed out */
73 static const value_string bssap_pdu_type_values[] = {
74     { BSSAP_PDU_TYPE_BSSMAP,    "BSS Management" },
75     { BSSAP_PDU_TYPE_DTAP,  "Direct Transfer" },
76     { 0,            NULL } };
77
78 static const value_string bsap_pdu_type_values[] = {
79     { BSSAP_PDU_TYPE_BSSMAP,    "BS Management" },
80     { BSSAP_PDU_TYPE_DTAP,  "Direct Transfer" },
81     { 0,            NULL } };
82
83 /* Same as above but in acronym for (for the Info column) */
84 static const value_string bssap_pdu_type_acro_values[] = {
85     { BSSAP_PDU_TYPE_BSSMAP,    "BSSMAP" },
86     { BSSAP_PDU_TYPE_DTAP,  "DTAP" },
87     { 0,            NULL } };
88
89 /* Same as above but in acronym for (for the Info column) */
90 static const value_string bsap_pdu_type_acro_values[] = {
91     { BSSAP_PDU_TYPE_BSSMAP,    "BSMAP" },
92     { BSSAP_PDU_TYPE_DTAP,  "DTAP" },
93     { 0,            NULL } };
94
95 #define PARAMETER_DLCI      0x00
96 #define PARAMETER_LENGTH    0x01
97 #define PARAMETER_DATA      0x02
98
99 #define DLCI_LENGTH     1
100 #define LENGTH_LENGTH       1
101 #define DATA_LENGTH     1
102
103 #define CC_MASK         0xc0
104 #define SPARE_MASK      0x38
105 #define SAPI_MASK       0x07
106
107 static guint global_bssap_ssn = 98;
108
109 static const value_string bssap_cc_values[] = {
110     { 0x00,     "not further specified" },
111     { 0x80,     "FACCH or SDCCH" },
112     { 0xc0,     "SACCH" },
113     { 0,        NULL } };
114
115 static const value_string bsap_cc_values[] = {
116     { 0x00,     "default for TIA/EIA/IS-2000" },
117     { 0,        NULL } };
118
119 static const value_string bssap_sapi_values[] = {
120     { 0x00,     "RR/MM/CC" },
121     { 0x03,     "SMS" },
122     { 0,        NULL } };
123
124 static const value_string bsap_sapi_values[] = {
125     { 0x00,     "Not used" },
126     { 0,        NULL } };
127
128 #define BSSAP_PAGING_REQUEST                1
129 #define BSSAP_PAGING_REJECT                 2                   /*  17.1.18 */
130 #define BSSAP_DOWNLINK_TUNNEL_REQUEST       7                   /*  17.1.4  */
131 #define BSSAP_UPLINK_TUNNEL_REQUEST         8                   /*  17.1.23 */
132 #define BSSAP_LOCATION_UPDATE_REQUEST       9                   /*  17.1.11 */
133 #define BSSAP_LOCATION_UPDATE_ACCEPT        10                  /*  17.1.9  */
134 #define BSSAP_LOCATION_UPDATE_REJECT        11                  /*  17.1.10 */
135 #define BSSAP_TMSI_REALLOCATION_COMPLETE    12                  /*  17.1.22 */
136 #define BSSAP_ALERT_REQUEST                 13                  /*  17.1.3  */
137 #define BSSAP_ALERT_ACK                     14                  /*  17.1.1  */
138 #define BSSAP_ALERT_REJECT                  15                  /*  17.1.2  */
139 #define BSSAP_MS_ACTIVITY_INDICATION        16                  /*  17.1.14 */
140 #define BSSAP_GPRS_DETACH_INDICATION        17                  /*  17.1.6  */
141 #define BSSAP_GPRS_DETACH_ACK               18                  /*  17.1.5  */
142 #define BSSAP_IMSI_DETACH_INDICATION        19                  /*  17.1.8  */
143 #define BSSAP_IMSI_DETACH_ACK               20                  /*  17.1.7  */
144 #define BSSAP_RESET_INDICATION              21                  /*  17.1.21 */
145 #define BSSAP_RESET_ACK                     22                  /*  17.1.20 */
146 #define BSSAP_MS_INFORMATION_REQUEST        23                  /*  17.1.15 */
147 #define BSSAP_MS_INFORMATION_RESPONSE       24                  /*  17.1.16 */
148 #define BSSAP_MM_INFORMATION_REQUEST        26                  /*  17.1.12 */
149 #define BSSAP_MOBILE_STATUS                 29                  /*  17.1.13 */
150 #define BSSAP_MS_UNREACHABLE                31                  /*  17.1.17 */
151
152 static const value_string bssap_plus_message_type_values[] = {
153     { 0x00,                                 "Unassigned: treated as an unknown Message type." },
154     { BSSAP_PAGING_REQUEST,                 "BSSAP+-PAGING-REQUEST" },                              /*  17.1.19 */
155     { BSSAP_PAGING_REJECT,                  "BSSAP+-PAGING-REJECT" },                               /*  17.1.18 */
156     { 0x03,                                 "Unassigned: treated as an unknown Message type." },
157     { 0x04,                                 "Unassigned: treated as an unknown Message type." },
158     { 0x05,                                 "Unassigned: treated as an unknown Message type." },
159     { 0x06,                                 "Unassigned: treated as an unknown Message type." },
160     { BSSAP_DOWNLINK_TUNNEL_REQUEST,        "BSSAP+-DOWNLINK-TUNNEL-REQUEST" },                     /*  17.1.4  */
161     { BSSAP_UPLINK_TUNNEL_REQUEST,          "BSSAP+-UPLINK-TUNNEL-REQUEST" },                       /*  17.1.23 */
162     { BSSAP_LOCATION_UPDATE_REQUEST,        "BSSAP+-LOCATION-UPDATE-REQUEST" },                     /*  17.1.11 */
163     { BSSAP_LOCATION_UPDATE_ACCEPT,         "BSSAP+-LOCATION-UPDATE-ACCEPT" },                      /*  17.1.9  */
164     { BSSAP_LOCATION_UPDATE_REJECT,         "BSSAP+-LOCATION-UPDATE-REJECT" },                      /*  17.1.10 */
165     { BSSAP_TMSI_REALLOCATION_COMPLETE,     "BSSAP+-TMSI-REALLOCATION-COMPLETE" },                  /*  17.1.22 */
166     { BSSAP_ALERT_REQUEST,                  "BSSAP+-ALERT-REQUEST" },                               /*  17.1.3  */
167     { BSSAP_ALERT_ACK,                      "BSSAP+-ALERT-ACK" },                                   /*  17.1.1  */
168     { BSSAP_ALERT_REJECT,                   "BSSAP+-ALERT-REJECT" },                                /*  17.1.2  */
169     { BSSAP_MS_ACTIVITY_INDICATION,         "BSSAP+-MS-ACTIVITY-INDICATION" },                      /*  17.1.14 */
170     { BSSAP_GPRS_DETACH_INDICATION,         "BSSAP+-GPRS-DETACH-INDICATION" },                      /*  17.1.6  */
171     { BSSAP_GPRS_DETACH_ACK,                "BSSAP+-GPRS-DETACH-ACK" },                             /*  17.1.5  */
172     { BSSAP_IMSI_DETACH_INDICATION,         "BSSAP+-IMSI-DETACH-INDICATION" },                      /*  17.1.8  */
173     { BSSAP_IMSI_DETACH_ACK,                "BSSAP+-IMSI-DETACH-ACK" },                             /*  17.1.7  */
174     { BSSAP_RESET_INDICATION,               "BSSAP+-RESET-INDICATION" },                            /*  17.1.21 */
175     { BSSAP_RESET_ACK,                      "BSSAP+-RESET-ACK" },                                   /*  17.1.20 */
176     { BSSAP_MS_INFORMATION_REQUEST,         "BSSAP+-MS-INFORMATION-REQUEST" },                      /*  17.1.15 */
177     { BSSAP_MS_INFORMATION_RESPONSE,        "BSSAP+-MS-INFORMATION-RESPONSE" },                     /*  17.1.16 */
178     { 0x19,                                 "Unassigned: treated as an unknown Message type." },
179     { BSSAP_MM_INFORMATION_REQUEST,         "BSSAP+-MM-INFORMATION-REQUEST" },                      /*  17.1.12 */
180     { BSSAP_MOBILE_STATUS,                  "BSSAP+-MOBILE-STATUS" },                               /*  17.1.13 */
181     { 0x1e,                                 "Unassigned: treated as an unknown Message type." },
182     { BSSAP_MS_UNREACHABLE,                 "BSSAP+-MS-UNREACHABLE" },                              /*  17.1.17 */
183     { 0,        NULL }
184 };
185
186 #define BSSAP_IMSI                      1
187 #define BSSAP_VLR_NUMBER                2
188 #define BSSAP_TMSI                      3
189 #define BSSAP_LOC_AREA_ID               4
190 #define BSSAP_CHANNEL_NEEDED            5
191 #define BSSAP_EMLPP_PRIORITY            6
192 #define BSSAP_TMSI_STATUS               7
193 #define BSSAP_GS_CAUSE                  8
194 #define BSSAP_SGSN_NUMBER               9
195 #define BSSAP_GPRS_LOC_UPD_TYPE         0x0a
196 #define BSSAP_GLOBAL_CN_ID              0x0b
197 #define BSSAP_MOBILE_STN_CLS_MRK1       0x0d
198 #define BSSAP_MOBILE_ID                 0x0e
199 #define BSSAP_REJECT_CAUSE              0x0f
200 #define BSSAP_IMSI_DET_FROM_GPRS_SERV_TYPE      0x10
201 #define BSSAP_IMSI_DET_FROM_NON_GPRS_SERV_TYPE  0x11
202 #define BSSAP_INFO_REQ                  0x12
203 #define BSSAP_PTMSI                     0x13
204 #define BSSAP_IMEI                      0x14
205 #define BSSAP_IMEISV                    0x15
206 #define BSSAP_MM_INFORMATION            0x17
207 #define BSSAP_CELL_GBL_ID               0x18
208 #define BSSAP_LOC_INF_AGE               0x19
209 #define BSSAP_MOBILE_STN_STATE          0x1a
210 #define BSSAP_SERVICE_AREA_ID           0x1e
211 #define BSSAP_ERRONEOUS_MSG             0x1b
212 #define BSSAP_DLINK_TNL_PLD_CTR_AND_INF 0x1c
213 #define BSSAP_ULINK_TNL_PLD_CTR_AND_INF 0x1d
214
215
216
217 static const value_string bssap_plus_ie_id_values[] = {
218     { BSSAP_IMSI,                               "IMSI" },                                       /* 18.4.10 */
219     { BSSAP_VLR_NUMBER,                         "VLR number" },                                 /* 18.4.26 */
220     { BSSAP_TMSI,                               "TMSI" },                                       /* 18.4.23 */
221     { BSSAP_LOC_AREA_ID,                        "Location area identifier" },                   /* 18.4.14 */
222     { BSSAP_CHANNEL_NEEDED,                     "Channel Needed" },                             /* 18.4.2  */
223     { BSSAP_EMLPP_PRIORITY,                     "eMLPP Priority" },                             /* 18.4.4  */
224     { BSSAP_TMSI_STATUS,                        "TMSI status" },                                /* 18.4.24 */
225     { BSSAP_GS_CAUSE,                           "Gs cause" },                                   /* 18.4.7  */
226     { BSSAP_SGSN_NUMBER,                        "SGSN number" },                                /* 18.4.22 */
227     { BSSAP_GPRS_LOC_UPD_TYPE,                  "GPRS location update type" },                  /* 18.4.6  */
228     { BSSAP_GLOBAL_CN_ID,                       "Global CN-Id" },                               /* 18.4.27 */
229     { 0x0c,                                     "Unassigned: treated as an unknown IEI." },     /* 18 and 16 */
230     { BSSAP_MOBILE_STN_CLS_MRK1,                "Mobile station classmark 1" },                 /* 18.4.18 */
231     { BSSAP_MOBILE_ID,                          "Mobile identity" },                            /* 18.4.17 */
232     { BSSAP_REJECT_CAUSE,                       "Reject cause" },                               /* 18.4.21 */
233     { BSSAP_IMSI_DET_FROM_GPRS_SERV_TYPE,       "IMSI detach from GPRS service type" },         /* 18.4.11 */
234     { BSSAP_IMSI_DET_FROM_NON_GPRS_SERV_TYPE,   "IMSI detach from non-GPRS service type" },     /* 18.4.12 */
235     { BSSAP_INFO_REQ,                           "Information requested" },                      /* 18.4.13 */
236     { BSSAP_PTMSI,                              "PTMSI" },                                      /* 18.4.20 */
237     { BSSAP_IMEI,                               "IMEI" },                                       /* 18.4.8  */
238     { BSSAP_IMEISV,                             "IMEISV" },                                     /* 18.4.9 */
239     { 0x16,                                     "Unassigned: treated as an unknown IEI." },     /* 18 and 16 */
240     { BSSAP_MM_INFORMATION,                     "MM information" },                             /* 18.4.16 */
241     { BSSAP_CELL_GBL_ID,                        "Cell Global Identity" },                       /* 18.4.1 */
242     { BSSAP_LOC_INF_AGE,                        "Location information age" },                   /* 18.4.15 */
243     { BSSAP_MOBILE_STN_STATE,                   "Mobile station state" },                       /* 18.4.19 */
244     { BSSAP_ERRONEOUS_MSG,                      "Erroneous message" },                          /* 18.4.5 */
245     { BSSAP_DLINK_TNL_PLD_CTR_AND_INF,          "Downlink Tunnel Payload Control and Info" },   /* 18.4.3 */
246     { BSSAP_ULINK_TNL_PLD_CTR_AND_INF,          "Uplink Tunnel Payload Control and Info" },     /* 18.4.25 */
247     { BSSAP_SERVICE_AREA_ID,                    "Service Area Identification" },                /* 18.4.21b */
248     { 0,                NULL }
249 };
250
251 /* Initialize the protocol and registered fields */
252 static int proto_bssap = -1;
253 /*static int proto_bssap_plus = -1;*/
254 static int hf_bssap_pdu_type = -1;
255 static int hf_bsap_pdu_type = -1;
256 static int hf_bssap_dlci_cc = -1;
257 static int hf_bsap_dlci_cc = -1;
258 static int hf_bssap_dlci_spare = -1;
259 static int hf_bsap_dlci_rsvd = -1;
260 static int hf_bssap_dlci_sapi = -1;
261 static int hf_bsap_dlci_sapi = -1;
262 static int hf_bssap_length = -1;
263 static int hf_bssap_plus_ie = -1;
264 static int hf_bssap_plus_ie_len = -1;
265
266 static int hf_bssap_plus_message_type = -1;
267 static int hf_bssap_imsi_ie = -1;
268 static int hf_bssap_imsi_det_from_gprs_serv_type_ie = -1;
269 static int hf_bssap_imsi_det_from_non_gprs_serv_type_ie = -1;
270 static int hf_bssap_info_req_ie = -1;
271 static int hf_bssap_loc_area_id_ie = -1;
272 static int hf_bssap_loc_inf_age_ie = -1;
273 static int hf_bssap_mm_information_ie = -1;
274 static int hf_bssap_mobile_id_ie = -1;
275 static int hf_bssap_mobile_stn_cls_mrk1_ie = -1;
276 static int hf_bssap_mobile_station_state_ie = -1;
277 static int hf_bssap_ptmsi_ie = -1;
278 static int hf_bssap_reject_cause_ie = -1;
279 static int hf_bssap_service_area_id_ie = -1;
280 static int hf_bssap_sgsn_nr_ie = -1;
281 static int hf_bssap_tmsi_ie = -1;
282 static int hf_bssap_tmsi_status_ie = -1;
283 static int hf_bssap_vlr_number_ie = -1;
284 static int hf_bssap_global_cn_id_ie = -1;
285 static int hf_bssap_plus_ie_data = -1;
286
287 static int hf_bssap_extension = -1;
288 static int hf_bssap_type_of_number = -1;
289 static int hf_bssap_numbering_plan_id = -1;
290 static int hf_bssap_sgsn_number = -1;
291 static int hf_bssap_vlr_number = -1;
292 static int hf_bssap_call_priority = -1;
293 static int hf_bssap_gprs_loc_upd_type_ie = -1;
294 static int hf_bssap_Gs_cause_ie = -1;
295 static int hf_bssap_imei_ie = -1;
296 static int hf_bssap_imesiv_ie = -1;
297 static int hf_bssap_cell_global_id_ie = -1;
298 static int hf_bssap_channel_needed_ie = -1;
299 static int hf_bssap_dlink_tnl_pld_cntrl_amd_inf_ie = -1;
300 static int hf_bssap_ulink_tnl_pld_cntrl_amd_inf_ie = -1;
301 static int hf_bssap_emlpp_prio_ie = -1;
302 static int hf_bssap_gprs_erroneous_msg_ie = -1;
303
304 static int hf_bssap_gprs_loc_upd_type = -1;
305 static int hf_bssap_Gs_cause = -1;
306 static int hf_bssap_imei = -1;
307 static int hf_bssap_imeisv = -1;
308 static int hf_bssap_imsi = -1;
309 static int hf_bssap_imsi_det_from_gprs_serv_type = -1;
310 static int hf_bssap_info_req = -1;
311 static int hf_bssap_loc_inf_age = -1;
312 static int hf_bssap_mobile_station_state = -1;
313 static int hf_bssap_ptmsi = -1;
314 static int hf_bssap_tmsi = -1;
315 static int hf_bssap_tmsi_status = -1;
316 static int hf_bssap_tom_prot_disc = -1;
317 static int hf_bssap_e_bit = -1;
318 static int hf_bssap_tunnel_prio = -1;
319 static int hf_bssap_global_cn_id = -1;
320 static int hf_bssap_plmn_id = -1;
321 static int hf_bssap_cn_id = -1;
322 static int hf_bssap_cell_global_id = -1;
323
324 /* Initialize the subtree pointers */
325 static gint ett_bssap = -1;
326 static gint ett_bssap_dlci = -1;
327 static gint ett_bssap_imsi = -1;
328 static gint ett_bssap_imsi_det_from_gprs_serv_type = -1;
329 static gint ett_bssap_imsi_det_from_non_gprs_serv_type = -1;
330 static gint ett_bssap_info_req = -1;
331 static gint ett_bssap_loc_area_id = -1;
332 static gint ett_bssap_loc_inf_age = -1;
333 static gint ett_bssap_mm_information = -1;
334 static gint ett_bssap_mobile_id = -1;
335 static gint ett_bssap_sgsn_nr = -1;
336 static gint ett_bssap_tmsi = -1;
337 static gint ett_bssap_tmsi_status = -1;
338 static gint ett_bssap_vlr_number = -1;
339 static gint ett_bssap_global_cn = -1;
340 static gint ett_bssap_gprs_loc_upd = -1;
341 static gint ett_bassp_Gs_cause = -1;
342 static gint ett_bassp_imei = -1;
343 static gint ett_bassp_imesiv = -1;
344 static gint ett_bssap_cell_global_id = -1;
345 static gint ett_bssap_cgi = -1;
346 static gint ett_bssap_channel_needed = -1;
347 static gint ett_bssap_dlink_tnl_pld_cntrl_amd_inf = -1;
348 static gint ett_bssap_ulink_tnl_pld_cntrl_amd_inf = -1;
349 static gint ett_bssap_emlpp_prio = -1;
350 static gint ett_bssap_erroneous_msg = -1;
351 static gint ett_bssap_mobile_stn_cls_mrk1 = -1;
352 static gint ett_bssap_mobile_station_state = -1;
353 static gint ett_bssap_ptmsi = -1;
354 static gint ett_bssap_reject_cause = -1;
355 static gint ett_bssap_service_area_id =-1;
356 static gint ett_bssap_global_cn_id = -1;
357 static gint ett_bssap_plmn = -1;
358
359 static dissector_handle_t data_handle;
360 static dissector_handle_t rrlp_handle;
361
362 static dissector_table_t bssap_dissector_table;
363 static dissector_table_t bsap_dissector_table;
364
365 static dissector_handle_t bsap_dissector_handle;
366
367 /*
368  * Keep track of pdu_type so we can call appropriate sub-dissector
369  */
370 static guint8   pdu_type = 0xFF;
371
372 static gint bssap_or_bsap_global = BSSAP_OR_BSAP_DEFAULT;
373
374 static gint    gsm_or_lb_interface_global = GSM_OR_LB_INTERFACE_DEFAULT;
375
376 static void
377 dissect_bssap_unknown_message(tvbuff_t *message_tvb, proto_tree *bssap_tree)
378 {
379     guint32 message_length;
380
381     message_length = tvb_length(message_tvb);
382
383     proto_tree_add_text(bssap_tree, message_tvb, 0, message_length,
384                 "Unknown message (%u byte%s)",
385                 message_length, plurality(message_length, "", "s"));
386 }
387
388 static void
389 dissect_bssap_unknown_param(tvbuff_t *tvb, proto_tree *tree, guint8 type, guint16 length)
390 {
391     proto_tree_add_text(tree, tvb, 0, length,
392                 "Unknown parameter 0x%x (%u byte%s)",
393                 type, length, plurality(length, "", "s"));
394 }
395
396 static void
397 dissect_bssap_data_param(tvbuff_t *tvb, packet_info *pinfo,
398             proto_tree *bssap_tree, proto_tree *tree)
399 {
400     if ((pdu_type <= 0x01))
401     {
402         if (bssap_or_bsap_global == BSSAP)
403         {
404             /* BSSAP */
405             if((gsm_or_lb_interface_global == LB_INTERFACE) && (pdu_type == BSSAP_PDU_TYPE_BSSMAP))
406             {
407                 bsap_dissector_handle = find_dissector("gsm_bssmap_le");
408
409                 if(bsap_dissector_handle == NULL) return;
410
411                 call_dissector(bsap_dissector_handle, tvb, pinfo, tree);
412
413                 return;
414             }
415             else if((gsm_or_lb_interface_global == GSM_INTERFACE) && (pdu_type == BSSAP_PDU_TYPE_BSSMAP))
416             {
417                 bsap_dissector_handle = find_dissector("gsm_a_bssmap");
418
419                 if(bsap_dissector_handle == NULL) return;
420
421                 call_dissector(bsap_dissector_handle, tvb, pinfo, tree);
422
423                 return;
424             }
425             else
426             {
427                 if (dissector_try_uint(bssap_dissector_table, pdu_type, tvb, pinfo, tree)) return;
428             }
429         }
430         else
431         {
432             /* BSAP */
433             if (dissector_try_uint(bsap_dissector_table, pdu_type, tvb, pinfo, tree))
434                 return;
435         }
436     }
437
438     /* No sub-dissection occured, treat it as raw data */
439     call_dissector(data_handle, tvb, pinfo, bssap_tree);
440 }
441
442 static void
443 dissect_bssap_dlci_param(tvbuff_t *tvb, proto_tree *tree, guint16 length)
444 {
445     proto_item  *dlci_item = 0;
446     proto_tree  *dlci_tree = 0;
447     guint8  oct;
448
449     dlci_item =
450         proto_tree_add_text(tree, tvb, 0, length,
451                     "Data Link Connection Identifier");
452
453     dlci_tree = proto_item_add_subtree(dlci_item, ett_bssap_dlci);
454
455     oct = tvb_get_guint8(tvb, 0);
456
457     if (bssap_or_bsap_global == BSSAP)
458     {
459         proto_tree_add_uint(dlci_tree, hf_bssap_dlci_cc, tvb, 0, length, oct);
460         proto_tree_add_uint(dlci_tree, hf_bssap_dlci_spare, tvb, 0, length, oct);
461         proto_tree_add_uint(dlci_tree, hf_bssap_dlci_sapi, tvb, 0, length, oct);
462     }
463     else
464     {
465         proto_tree_add_uint(dlci_tree, hf_bsap_dlci_cc, tvb, 0, length, oct);
466         proto_tree_add_uint(dlci_tree, hf_bsap_dlci_rsvd, tvb, 0, length, oct);
467         proto_tree_add_uint(dlci_tree, hf_bsap_dlci_sapi, tvb, 0, length, oct);
468     }
469 }
470
471 static void
472 dissect_bssap_length_param(tvbuff_t *tvb, proto_tree *tree, guint16 length)
473 {
474     guint8  data_length;
475
476     data_length = tvb_get_guint8(tvb, 0);
477     proto_tree_add_uint(tree, hf_bssap_length, tvb, 0, length, data_length);
478 }
479
480 /*
481  * Dissect a parameter given its type, offset into tvb, and length.
482  */
483 static guint16
484 dissect_bssap_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bssap_tree,
485                proto_tree *tree, guint8 parameter_type, gint offset,
486                guint16 parameter_length)
487 {
488     tvbuff_t *parameter_tvb;
489
490     parameter_tvb = tvb_new_subset(tvb, offset, parameter_length, parameter_length);
491
492     switch (parameter_type)
493     {
494     case PARAMETER_DLCI:
495         dissect_bssap_dlci_param(parameter_tvb, bssap_tree, parameter_length);
496         break;
497
498     case PARAMETER_LENGTH:
499         dissect_bssap_length_param(parameter_tvb, bssap_tree, parameter_length);
500         break;
501
502     case PARAMETER_DATA:
503         dissect_bssap_data_param(parameter_tvb, pinfo, bssap_tree, tree);
504         break;
505
506     default:
507         dissect_bssap_unknown_param(parameter_tvb, bssap_tree, parameter_type,
508                         parameter_length);
509         break;
510     }
511
512     return(parameter_length);
513 }
514
515 static guint16
516 dissect_bssap_var_parameter(tvbuff_t *tvb, packet_info *pinfo,
517                 proto_tree *bssap_tree, proto_tree *tree,
518                 guint8 parameter_type, gint offset)
519 {
520     guint16 parameter_length;
521     guint8  length_length;
522
523     parameter_length = tvb_get_guint8(tvb, offset);
524     length_length = LENGTH_LENGTH;
525
526     offset += length_length;
527
528     dissect_bssap_parameter(tvb, pinfo, bssap_tree, tree, parameter_type,
529                 offset, parameter_length);
530
531     return(parameter_length + length_length);
532 }
533
534 static void
535 dissect_bssap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bssap_tree,
536              proto_tree *tree)
537 {
538     gint    offset = 0;
539
540     /*
541      * Extract the PDU type
542      */
543     pdu_type = tvb_get_guint8(tvb, PDU_TYPE_OFFSET);
544     offset = PDU_TYPE_LENGTH;
545
546     if (bssap_tree)
547     {
548         /*
549          * add the message type to the protocol tree
550          */
551         proto_tree_add_uint(bssap_tree,
552                     (bssap_or_bsap_global == BSSAP) ? hf_bssap_pdu_type : hf_bsap_pdu_type,
553                     tvb, PDU_TYPE_OFFSET, PDU_TYPE_LENGTH, pdu_type);
554     }
555
556     /* Starting a new message dissection */
557
558     switch (pdu_type)
559     {
560     case BSSAP_PDU_TYPE_BSSMAP:
561         offset += dissect_bssap_parameter(tvb, pinfo, bssap_tree, tree,
562                           PARAMETER_LENGTH, offset,
563                           LENGTH_LENGTH);
564         offset += dissect_bssap_var_parameter(tvb, pinfo, bssap_tree, tree,
565                               PARAMETER_DATA,
566                               (offset - LENGTH_LENGTH));
567         break;
568
569     case BSSAP_PDU_TYPE_DTAP:
570         offset += dissect_bssap_parameter(tvb, pinfo, bssap_tree, tree,
571                           PARAMETER_DLCI,
572                           offset, DLCI_LENGTH);
573         offset += dissect_bssap_parameter(tvb, pinfo, bssap_tree, tree,
574                           PARAMETER_LENGTH, offset,
575                           LENGTH_LENGTH);
576         offset += dissect_bssap_var_parameter(tvb, pinfo, bssap_tree, tree,
577                               PARAMETER_DATA,
578                               (offset - LENGTH_LENGTH));
579         break;
580
581     default:
582         col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
583                 val_to_str(pdu_type, ((bssap_or_bsap_global == BSSAP) ?
584                               bssap_pdu_type_acro_values : bsap_pdu_type_acro_values),
585                        "Unknown"));
586         dissect_bssap_unknown_message(tvb, bssap_tree);
587         break;
588     }
589 }
590
591 static void
592 dissect_bssap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
593 {
594     proto_item  *bssap_item, *hidden_item;
595     proto_tree  *bssap_tree = NULL;
596
597     /*
598      * Make entry in the Protocol column on summary display
599      */
600     col_set_str(pinfo->cinfo, COL_PROTOCOL, ((bssap_or_bsap_global == BSSAP) ? "BSSAP" : "BSAP"));
601
602     if ( pinfo->sccp_info && pinfo->sccp_info->data.co.assoc  )
603         pinfo->sccp_info->data.co.assoc->payload = SCCP_PLOAD_BSSAP;
604
605     /*
606      * create the bssap protocol tree
607      */
608     hidden_item = proto_tree_add_item(tree, proto_bssap, tvb, 0, -1, ENC_BIG_ENDIAN);
609     PROTO_ITEM_SET_HIDDEN(hidden_item);
610     bssap_item = proto_tree_add_text(tree, tvb, 0, -1, (bssap_or_bsap_global == BSSAP) ? "BSSAP" : "BSAP");
611     bssap_tree = proto_item_add_subtree(bssap_item, ett_bssap);
612
613     /* dissect the message */
614
615     dissect_bssap_message(tvb, pinfo, bssap_tree, tree);
616 }
617
618
619 /*
620  * BSSAP+ Routines
621  */
622
623 #ifdef REMOVED
624 static dgt_set_t Dgt_tbcd = {
625     {
626   /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e */
627      '0','1','2','3','4','5','6','7','8','9','?','B','C','*','#'
628     }
629 };
630 #endif
631
632 static dgt_set_t Dgt1_9_bcd = {
633     {
634   /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e */
635      '0','1','2','3','4','5','6','7','8','9','?','?','?','?','?'
636     }
637 };
638 /* Assumes the rest of the tvb contains the digits to be turned into a string
639  */
640 static const char*
641 unpack_digits(tvbuff_t *tvb, int offset,dgt_set_t *dgt,gboolean skip_first){
642
643     int length;
644     guint8 octet;
645     int i=0;
646     char *digit_str;
647
648     length = tvb_length(tvb);
649     if (length < offset)
650         return "";
651     digit_str = ep_alloc((length - offset)*2+1);
652
653     while ( offset < length ){
654
655         octet = tvb_get_guint8(tvb,offset);
656         if (!skip_first){
657             digit_str[i] = dgt->out[octet & 0x0f];
658             i++;
659         }
660         skip_first = FALSE;
661
662         /*
663          * unpack second value in byte
664          */
665         octet = octet >> 4;
666
667         if (octet == 0x0f)  /* odd number bytes - hit filler */
668             break;
669
670         digit_str[i] = dgt->out[octet & 0x0f];
671         i++;
672         offset++;
673
674     }
675     digit_str[i]= '\0';
676     return digit_str;
677 }
678
679 static gboolean
680 check_ie(tvbuff_t *tvb, proto_tree *tree, int *offset, guint8 expected_ie){
681     guint8  ie_type;
682     guint8  ie_len;
683
684     ie_type = tvb_get_guint8(tvb,*offset);
685     if (ie_type != expected_ie){
686         proto_tree_add_text(tree, tvb, *offset, 1, "Mandatory IE %s expected but IE %s Found",
687                             val_to_str(expected_ie,bssap_plus_ie_id_values,"Unknown %u"),
688                             val_to_str(ie_type,bssap_plus_ie_id_values,"Unknown %u"));
689         (*offset)++;
690         ie_len = tvb_get_guint8(tvb,*offset);
691         *offset = *offset + ie_len;
692         return FALSE;
693     }
694
695     return TRUE;
696
697 }
698
699 static gboolean
700 check_optional_ie(tvbuff_t *tvb, int offset, guint8 expected_ie){
701     guint8  ie_type;
702
703     ie_type = tvb_get_guint8(tvb,offset);
704     if (ie_type != expected_ie){
705         return FALSE;
706     }
707     return TRUE;
708
709 }
710
711 /* 18.4.1 Cell global identity */
712 static int
713 dissect_bssap_cell_global_id(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset)
714 {
715     proto_item  *item = NULL;
716     proto_tree  *ie_tree = NULL;
717     proto_item  *cgi_item = NULL;
718     proto_tree  *cgi_tree = NULL;
719     guint8           ie_len;
720
721     ie_len = tvb_get_guint8(tvb,offset+1);
722     item = proto_tree_add_item(tree, hf_bssap_cell_global_id_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
723     ie_tree = proto_item_add_subtree(item, ett_bssap_cell_global_id);
724
725     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
726     offset++;
727     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
728     offset++;
729     /*
730      * The rest of the information element is coded as the the value part
731      * of the cell global id IE defined in 3GPP TS 48.018 (not including
732      * 3GPP TS 48.018 IEI and 3GPP TS 48.018 length indicator).
733      */
734     cgi_item= proto_tree_add_item(ie_tree, hf_bssap_cell_global_id, tvb, offset, ie_len, ENC_BIG_ENDIAN);
735     cgi_tree = proto_item_add_subtree(cgi_item, ett_bssap_cgi);
736     /*  octets 3-8 Octets 3 to 8 contain the value part (starting with octet 2) of the
737      *  Routing Area Identification IE defined in 3GPP TS 24.008, not
738      *  including 3GPP TS 24.008 IEI
739      */
740     de_gmm_rai(tvb, cgi_tree, pinfo, offset, ie_len, NULL, 0);
741     /*  Octets 9 and 10 contain the value part (starting with octet 2) of the
742      *  Cell Identity IE defined in 3GPP TS 24.008, not including
743      *  3GPP TS 24.008 IEI
744      */
745     offset = offset + 6;
746     de_cell_id(tvb, cgi_tree, pinfo, offset, ie_len, NULL, 0);
747     offset = offset + 2;
748
749     return offset;
750
751 }
752 /* 18.4.2 Channel needed */
753 static int
754 dissect_bssap_channel_needed(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset)
755 {
756     proto_item  *item = NULL;
757     proto_tree  *ie_tree = NULL;
758     guint8           ie_len;
759
760     ie_len = tvb_get_guint8(tvb,offset+1);
761     item = proto_tree_add_item(tree, hf_bssap_channel_needed_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
762     ie_tree = proto_item_add_subtree(item, ett_bssap_channel_needed);
763
764     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
765     offset++;
766     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
767     offset++;
768     /*
769      * The rest of the information element is coded as the IEI part and the
770      * value part of the Channel Needed IE defined in 3GPP TS 44.018.
771      * 10.5.2.8 Channel Needed
772      */
773     de_rr_chnl_needed(tvb, ie_tree, pinfo, offset, ie_len, NULL, 0);
774
775     return offset + ie_len;
776
777 }
778 /* 18.4.3 Downlink Tunnel Payload Control and Info */
779 static int
780 dissect_bssap_dlink_tunnel_payload_control_and_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
781 {
782     proto_item *item = NULL;
783     proto_tree *ie_tree = NULL;
784     tvbuff_t *next_tvb;
785     guint8 ie_len;
786     guint8 octet;
787     guint8 prot_disc;
788
789     ie_len = tvb_get_guint8(tvb,offset+1);
790     item = proto_tree_add_item(tree, hf_bssap_dlink_tnl_pld_cntrl_amd_inf_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
791     ie_tree = proto_item_add_subtree(item, ett_bssap_dlink_tnl_pld_cntrl_amd_inf);
792
793     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
794     offset++;
795     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
796     offset++;
797     /* Bit 8 Spare */
798     /* Bit 7 - 4
799      * TOM Protocol Discriminator: Identifies the protocol using tunnelling of non-GSM signalling.
800      * For coding, see 3GPP TS 44.064.
801      */
802
803     proto_tree_add_item(ie_tree, hf_bssap_tom_prot_disc, tvb, offset, 1, ENC_BIG_ENDIAN);
804     octet = tvb_get_guint8(tvb,offset);
805     prot_disc = (octet&0x78)>>3;
806
807     /* octet 3 bit 3 E: Cipher Request. When set to 1 indicates that the SGSN received the payload in ciphered form,
808      * when set to 0 indicates that the SGSN did not receive the payload in ciphered form.
809      */
810     proto_tree_add_item(ie_tree, hf_bssap_e_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
811
812     /* octet 3 bit 2 - 1
813      * Tunnel Priority: Indicates the priority of the Tunnel Payload. For coding, see Table 20.1: Association
814      * between Tunnel Priority and LLC SAPs.
815      */
816     proto_tree_add_item(ie_tree, hf_bssap_tunnel_prio, tvb, offset, 1, ENC_BIG_ENDIAN);
817     /* Tunnel payload */
818     next_tvb = tvb_new_subset(tvb, offset, ie_len-4, ie_len-4);
819
820     if ((prot_disc == 2)&&(rrlp_handle))
821         call_dissector(rrlp_handle, next_tvb, pinfo, ie_tree);
822     else
823         call_dissector(data_handle, next_tvb, pinfo, ie_tree);
824
825
826     return offset + ie_len;
827
828 }
829
830 /* 18.4.4 eMLPP Priority */
831 /* Call priority */
832 static const value_string bssap_call_priority_values[] = {
833     { 0x00,             "No priority applied" },
834     { 0x01,             "Call priority level 4" },
835     { 0x02,             "Call priority level 3" },
836     { 0x03,             "Call priority level 2" },
837     { 0x04,             "Call priority level 1" },
838     { 0x05,             "Call priority level 0" },
839     { 0x06,             "Call priority level B" },
840     { 0x07,             "Call priority level A" },
841     { 0,                NULL }
842 };
843 static int
844 dissect_bssap_emlpp_priority(tvbuff_t *tvb, proto_tree *tree, int offset)
845 {
846     proto_item  *item = NULL;
847     proto_tree  *ie_tree = NULL;
848     guint8 ie_len;
849
850     ie_len = tvb_get_guint8(tvb,offset+1);
851     item = proto_tree_add_item(tree, hf_bssap_emlpp_prio_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
852     ie_tree = proto_item_add_subtree(item, ett_bssap_emlpp_prio);
853
854     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
855     offset++;
856     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
857     offset++;
858     /*  The rest of the information element is coded as the value part of
859         the eMLPP-Priority IE defined in 3GPP TS 48.008 (not including
860         3GPP TS 48.008 IEI and 3GPP TS 48.008 length indicator).
861         3.2.2.56 eMLPP Priority
862         The call priority field (bit 3 to 1 of octet 2) is coded in the same way
863         as the call priority field (bit 3 to 1 of octet 5) in the Descriptive group
864         or broadcast call reference information element as defined in 3GPP TS 24.008.
865      */
866     proto_tree_add_item(ie_tree, hf_bssap_call_priority, tvb, offset, ie_len, ENC_BIG_ENDIAN);
867
868     return offset + ie_len;
869
870 }
871 /* 18.4.5 Erroneous message */
872     /* Erroneous message including the message type. */
873
874 static int
875 dissect_bssap_gprs_erroneous_msg(tvbuff_t *tvb, proto_tree *tree, int offset)
876 {
877     proto_item  *item = NULL;
878     proto_tree  *ie_tree = NULL;
879     guint8 ie_len;
880
881     ie_len = tvb_get_guint8(tvb,offset+1);
882     item = proto_tree_add_item(tree, hf_bssap_gprs_erroneous_msg_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
883     ie_tree = proto_item_add_subtree(item, ett_bssap_erroneous_msg);
884
885     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
886     offset++;
887     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
888     offset++;
889
890     /* Erroneous message including the message type. */
891     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_data, tvb, offset, ie_len, ENC_BIG_ENDIAN);
892
893     return offset + ie_len;
894
895 }
896
897
898 static const value_string bssap_plus_GPRS_loc_upd_type_values[] = {
899     { 0x00,             "Shall not be sent in this version of the protocol. If received, shall be treated as '00000010'." },
900     { 0x01,             "IMSI attach" },
901     { 0x02,             "Normal location update" },
902     { 0,                NULL }
903 };
904 /* 18.4.6 GPRS location update type */
905 static int
906 dissect_bssap_gprs_location_update_type(tvbuff_t *tvb, proto_tree *tree, int offset)
907 {
908     proto_item  *item = NULL;
909     proto_tree  *ie_tree = NULL;
910     guint8 ie_len;
911
912     ie_len = tvb_get_guint8(tvb,offset+1);
913     item = proto_tree_add_item(tree, hf_bssap_gprs_loc_upd_type_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
914     ie_tree = proto_item_add_subtree(item, ett_bssap_gprs_loc_upd);
915
916     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
917     offset++;
918     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
919     offset++;
920
921     /* GPRS location update type value (octet 3) */
922     proto_tree_add_item(ie_tree, hf_bssap_gprs_loc_upd_type, tvb, offset, ie_len, ENC_BIG_ENDIAN);
923
924     return offset + ie_len;
925 }
926
927 /* Gs Cause value (octet 3) */
928 static const value_string bssap_Gs_cause_values[] = {
929
930     { 0x00,     "Normal, unspecified in this version of the protocol." },
931     { 0x01,     "IMSI detached for GPRS services" },
932     { 0x02,     "IMSI detached for GPRS and non-GPRS services" },
933     { 0x03,     "IMSI unknown" },
934     { 0x04,     "IMSI detached for non-GPRS services" },
935     { 0x05,     "IMSI implicitly detached for non-GPRS services" },
936     { 0x06,     "MS unreachable" },
937     { 0x07,     "Message not compatible with the protocol state" },
938     { 0x08,     "Missing mandatory information element" },
939     { 0x09,     "Invalid mandatory information" },
940     { 0x0a,     "Conditional IE error" },
941     { 0x0b,     "Semantically incorrect message" },
942     { 0x0c,     "Message unknown" },
943     { 0x0d,     "Address error" },
944     { 0x0e,     "TOM functionality not supported" },
945     { 0x0f,     "Ciphering request cannot be accommodated" },
946     { 0,        NULL }
947 };
948
949 /* 18.4.7 Gs cause */
950 static int
951 dissect_bssap_Gs_cause(tvbuff_t *tvb, proto_tree *tree, int offset)
952 {
953     proto_item  *item = NULL;
954     proto_tree  *ie_tree = NULL;
955     guint8 ie_len;
956
957     ie_len = tvb_get_guint8(tvb,offset+1);
958     item = proto_tree_add_item(tree, hf_bssap_Gs_cause_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
959     ie_tree = proto_item_add_subtree(item, ett_bassp_Gs_cause);
960
961     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
962     offset++;
963     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
964     offset++;
965     /* Gs Cause value (octet 3) */
966     proto_tree_add_item(ie_tree, hf_bssap_Gs_cause, tvb, offset, ie_len, ENC_BIG_ENDIAN);
967
968
969     return offset + ie_len;
970
971 }
972 /* 18.4.8 IMEI */
973 static int
974 dissect_bssap_imei(tvbuff_t *tvb, proto_tree *tree, int offset)
975 {
976     proto_item *item = NULL;
977     proto_tree *ie_tree = NULL;
978     guint8 ie_len;
979     tvbuff_t *ie_tvb;
980     const char *digit_str;
981
982     ie_len = tvb_get_guint8(tvb,offset+1);
983     item = proto_tree_add_item(tree, hf_bssap_imei_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
984     ie_tree = proto_item_add_subtree(item, ett_bassp_imei);
985
986     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
987     offset++;
988     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
989     offset++;
990     /* The IMEI is coded as a sequence of BCD digits, compressed two into each octet.
991      * The IMEI consists of 15 digits (see 3GPP TS 23.003).
992      */
993     ie_tvb = tvb_new_subset(tvb, offset, ie_len, ie_len);
994     digit_str = unpack_digits(ie_tvb, 0, &Dgt1_9_bcd, ENC_BIG_ENDIAN);
995     proto_tree_add_string(ie_tree, hf_bssap_imei, ie_tvb, 0, -1, digit_str);
996
997     return offset + ie_len;
998
999 }
1000 /* 18.4.9 IMEISV */
1001 static int
1002 dissect_bssap_imesiv(tvbuff_t *tvb, proto_tree *tree, int offset)
1003 {
1004     proto_item *item = NULL;
1005     proto_tree *ie_tree = NULL;
1006     guint8 ie_len;
1007     tvbuff_t *ie_tvb;
1008     const char *digit_str;
1009
1010     ie_len = tvb_get_guint8(tvb,offset+1);
1011     item = proto_tree_add_item(tree, hf_bssap_imesiv_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1012     ie_tree = proto_item_add_subtree(item, ett_bassp_imesiv);
1013
1014     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1015     offset++;
1016     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1017     offset++;
1018     /*  The IMEISV is coded as a sequence of BCD digits, compressed two into each octet.
1019      *  The IMEISV consists of 16 digits (see 3GPP TS 23.003).
1020      */
1021     ie_tvb = tvb_new_subset(tvb, offset, ie_len, ie_len);
1022     digit_str = unpack_digits(ie_tvb, 0, &Dgt1_9_bcd, ENC_BIG_ENDIAN);
1023     proto_tree_add_string(ie_tree, hf_bssap_imeisv, ie_tvb, 0, -1, digit_str);
1024
1025     return offset + ie_len;
1026
1027 }
1028 /* 18.4.10 IMSI
1029  * The IMSI is coded as a sequence of BCD digits, compressed two into each octet.
1030  * This is a variable length element, and includes a length indicator.
1031  * The IMSI is defined in 3GPP TS 23.003. It shall not exceed 15 digits (see 3GPP TS 23.003).
1032  */
1033
1034
1035 static int
1036 dissect_bssap_imsi(tvbuff_t *tvb, proto_tree *tree, int offset)
1037 {
1038     proto_item *item = NULL;
1039     proto_tree *ie_tree = NULL;
1040     guint8 ie_len;
1041     tvbuff_t *ie_tvb;
1042     const char *digit_str;
1043
1044     ie_len = tvb_get_guint8(tvb,offset+1);
1045     item = proto_tree_add_item(tree, hf_bssap_imsi_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1046     ie_tree = proto_item_add_subtree(item, ett_bssap_imsi);
1047
1048     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1049     offset++;
1050     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1051     offset++;
1052     ie_tvb = tvb_new_subset(tvb, offset, ie_len,ie_len);
1053     digit_str = unpack_digits(ie_tvb, 0, &Dgt1_9_bcd, TRUE);
1054     proto_tree_add_string(ie_tree, hf_bssap_imsi, ie_tvb, 0, -1, digit_str);
1055
1056     return offset + ie_len;
1057
1058 }
1059 static const value_string bssap_imsi_det_from_gprs_serv_type_values[] _U_ = {
1060     { 0x00,     "Interpreted as reserved in this version of the protocol" },
1061     { 0x01,     "Network initiated IMSI detach from GPRS service" },
1062     { 0x02,     "MS initiated IMSI detach from GPRS service" },
1063     { 0x03,     "GPRS services not allowed" },
1064     { 0,                NULL }
1065 };
1066
1067 /* 18.4.11 IMSI detach from GPRS service type */
1068 static int
1069 dissect_bssap_imsi_det_from_gprs_serv_type(tvbuff_t *tvb, proto_tree *tree, int offset)
1070 {
1071     proto_item  *item = NULL;
1072     proto_tree  *ie_tree = NULL;
1073     guint8 ie_len;
1074
1075     ie_len = tvb_get_guint8(tvb,offset+1);
1076     item = proto_tree_add_item(tree, hf_bssap_imsi_det_from_gprs_serv_type_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1077     ie_tree = proto_item_add_subtree(item, ett_bssap_imsi_det_from_gprs_serv_type);
1078
1079     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1080     offset++;
1081     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1082     offset++;
1083     /* IMSI detach from GPRS service type value (octet 3)*/
1084     proto_tree_add_item(ie_tree, hf_bssap_imsi_det_from_gprs_serv_type, tvb, offset, ie_len, ENC_BIG_ENDIAN);
1085
1086
1087     return offset + ie_len;
1088
1089 }
1090 /* 18.4.12 IMSI detach from non-GPRS service type */
1091 static int
1092 dissect_bssap_imsi_det_from_non_gprs_serv_type(tvbuff_t *tvb, proto_tree *tree, int offset)
1093 {
1094     proto_item  *item = NULL;
1095     proto_tree  *ie_tree = NULL;
1096     guint8 ie_len;
1097
1098     ie_len = tvb_get_guint8(tvb,offset+1);
1099     item = proto_tree_add_item(tree, hf_bssap_imsi_det_from_non_gprs_serv_type_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1100     ie_tree = proto_item_add_subtree(item, ett_bssap_imsi_det_from_non_gprs_serv_type);
1101
1102     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1103     offset++;
1104     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1105     offset++;
1106     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_data, tvb, offset, ie_len, ENC_BIG_ENDIAN);
1107
1108
1109     return offset + ie_len;
1110
1111 }
1112 static const value_string bssap_info_req_values[] = {
1113     { 0x00,     "Interpreted as Not supported in this version of the protocol." },
1114     { 0x01,     "PTMSI" },
1115     { 0x02,     "IMEI" },
1116     { 0x03,     "IMEISV" },
1117     { 0x04,     "PTMSI and IMEI" },
1118     { 0x05,     "PTMSI and IMEISV" },
1119     { 0x06,     "IMEI and IMEISV" },
1120     { 0x07,     "PTMSI, IMEI, and IMEISV" },
1121     { 0x08,     "Mobile location information" },
1122     { 0x09,     "TMSI" },
1123     { 0,                NULL }
1124 };
1125 /* 18.4.13 Information requested */
1126 static int
1127 dissect_bssap_info_req(tvbuff_t *tvb, proto_tree *tree, int offset)
1128 {
1129     proto_item  *item = NULL;
1130     proto_tree  *ie_tree = NULL;
1131     guint8 ie_len;
1132
1133     ie_len = tvb_get_guint8(tvb,offset+1);
1134     item = proto_tree_add_item(tree, hf_bssap_info_req_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1135     ie_tree = proto_item_add_subtree(item, ett_bssap_info_req);
1136
1137     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1138     offset++;
1139     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1140     offset++;
1141     /*Information requested value (octet 3) */
1142     proto_tree_add_item(ie_tree, hf_bssap_info_req, tvb, offset, ie_len, ENC_BIG_ENDIAN);
1143
1144
1145     return offset + ie_len;
1146
1147 }
1148 /* 18.4.14 Location area identifier */
1149 static int
1150 dissect_bssap_loc_area_id(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset)
1151 {
1152     proto_item  *item = NULL;
1153     proto_tree  *ie_tree = NULL;
1154     guint8 ie_len;
1155
1156     ie_len = tvb_get_guint8(tvb,offset+1);
1157     item = proto_tree_add_item(tree, hf_bssap_loc_area_id_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1158     ie_tree = proto_item_add_subtree(item, ett_bssap_loc_area_id);
1159
1160     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1161     offset++;
1162     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1163     offset++;
1164     /*  The rest of the information element is coded as the value part of
1165      *  the location area identifier IE defined in 3GPP TS 48.018 (not
1166      *  including 3GPP TS 48.018 IEI and 3GPP TS 48.018 length
1167      *  indicator).
1168      */
1169     de_lai(tvb, ie_tree, pinfo, offset, ie_len, NULL, 0);
1170
1171     return offset + ie_len;
1172
1173 }
1174 /* 18.4.15 Location information age */
1175 static int
1176 dissect_bssap_location_information_age(tvbuff_t *tvb, proto_tree *tree, int offset)
1177 {
1178     proto_item  *item = NULL;
1179     proto_tree  *ie_tree = NULL;
1180     guint8 ie_len;
1181
1182     ie_len = tvb_get_guint8(tvb,offset+1);
1183     item = proto_tree_add_item(tree, hf_bssap_loc_inf_age_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1184     ie_tree = proto_item_add_subtree(item, ett_bssap_loc_inf_age);
1185
1186     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1187     offset++;
1188     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1189     offset++;
1190     /* The rest of the IE is coded as the value part of the
1191      * AgeOfLocationInformation as specified in 3GPP TS 29.002.:
1192      *   AgeOfLocationInformation ::= INTEGER (0..32767)
1193      * -- the value represents the elapsed time in minutes since the last
1194      * -- network contact of the mobile station (i.e. the actuality of the
1195      * -- location information).
1196      * -- value '0' indicates that the MS is currently in contact with the
1197      * -- network
1198      * -- value '32767' indicates that the location information is at least
1199      * -- 32767 minutes old
1200      */
1201     proto_tree_add_item(ie_tree, hf_bssap_loc_inf_age, tvb, offset, ie_len, ENC_BIG_ENDIAN);
1202
1203
1204     return offset + ie_len;
1205
1206 }
1207 /* 18.4.16 MM information */
1208 static int
1209 dissect_bssap_MM_information(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset)
1210 {
1211     proto_item  *item = NULL;
1212     proto_tree  *ie_tree = NULL;
1213     guint8 ie_len;
1214
1215     ie_len = tvb_get_guint8(tvb,offset+1);
1216     item = proto_tree_add_item(tree, hf_bssap_mm_information_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1217     ie_tree = proto_item_add_subtree(item, ett_bssap_mm_information);
1218
1219     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1220     offset++;
1221     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1222     offset++;
1223     /* User information: This field is composed of one or more of the
1224      *  information elements of the MM information message as defined
1225      *  3GPP TS 24.008, excluding the Protocol discriminator, Skip
1226      *  indicator and Message type. This field includes the IEI and length
1227      *  indicatior of the other information elements.
1228      */
1229     dtap_mm_mm_info(tvb, ie_tree, pinfo, offset, ie_len);
1230
1231
1232     return offset + ie_len;
1233
1234 }
1235 /* 18.4.17 Mobile identity */
1236 static int
1237 dissect_bssap_mobile_id(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset)
1238 {
1239     proto_item  *item = NULL;
1240     proto_tree  *ie_tree = NULL;
1241     guint ie_len;
1242
1243     ie_len = tvb_get_guint8(tvb,offset+1);
1244     item = proto_tree_add_item(tree, hf_bssap_mobile_id_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1245     ie_tree = proto_item_add_subtree(item, ett_bssap_mobile_id);
1246
1247     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1248     offset++;
1249     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1250     offset++;
1251     /*  The rest of the information element is coded as the value part of
1252      *  the mobile identity IE defined in 3GPP TS 24.008 (not including
1253      *  3GPP TS 24.008 IEI and 3GPP TS 24.008 length indicator).
1254      */
1255     de_mid(tvb, ie_tree, pinfo, offset, ie_len, NULL, 0);
1256
1257
1258     return offset + ie_len;
1259
1260 }
1261 /* 18.4.18 Mobile station classmark 1 */
1262 static int
1263 dissect_bssap_mobile_stn_cls_mrk1(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset)
1264 {
1265     proto_item  *item = NULL;
1266     proto_tree  *ie_tree = NULL;
1267     guint8 ie_len;
1268
1269     ie_len = tvb_get_guint8(tvb,offset+1);
1270     item = proto_tree_add_item(tree, hf_bssap_mobile_stn_cls_mrk1_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1271     ie_tree = proto_item_add_subtree(item, ett_bssap_mobile_stn_cls_mrk1);
1272
1273     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1274     offset++;
1275     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1276     offset++;
1277     /*  The rest of the information element is coded as the value part of
1278      *  the mobile station classmark 1 IE defined in 3GPP TS 24.008 (not
1279      *  including 3GPP TS 24.008 IEI)
1280      */
1281     de_ms_cm_1(tvb, ie_tree, pinfo, offset, ie_len, NULL, 0);
1282
1283     return offset + ie_len;
1284
1285 }
1286 /* 18.4.19 Mobile station state */
1287 static const value_string bssap_mobile_station_state_values[] = {
1288     { 0x00,     "IDLE or PMM-DETACHED" },
1289     { 0x01,     "STANDBY or PMM-IDLE, 0 PDP contexts active" },
1290     { 0x02,     "STANDBY or PMM-IDLE, 1 or more PDP contexts active" },
1291     { 0x03,     "SUSPENDED, 0 PDP contexts active" },
1292     { 0x04,     "SUSPENDED, 1 or more PDP contexts active" },
1293     { 0x05,     "READY or PMM-CONNECTED, 0 PDP contexts active" },
1294     { 0x06,     "READY or PMM-CONNECTED, 1 or more PDP contexts active" },
1295     { 0x07,     "IMSI unknown" },
1296     { 0x08,     "Information requested not supported" },
1297     { 0,                NULL }
1298 };
1299 static int
1300 dissect_bssap_mobile_station_state(tvbuff_t *tvb, proto_tree *tree, int offset)
1301 {
1302     proto_item  *item = NULL;
1303     proto_tree  *ie_tree = NULL;
1304     guint8 ie_len;
1305
1306     ie_len = tvb_get_guint8(tvb,offset+1);
1307     item = proto_tree_add_item(tree, hf_bssap_mobile_station_state_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1308     ie_tree = proto_item_add_subtree(item, ett_bssap_mobile_station_state);
1309
1310     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1311     offset++;
1312     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1313     offset++;
1314     /* Mobile station state value (octet 3) */
1315     proto_tree_add_item(ie_tree, hf_bssap_mobile_station_state, tvb, offset, ie_len, ENC_BIG_ENDIAN);
1316
1317     return offset + ie_len;
1318
1319 }
1320 /* 18.4.20 PTMSI */
1321 static int
1322 dissect_bssap_ptmsi(tvbuff_t *tvb, proto_tree *tree, int offset)
1323 {
1324     proto_item  *item = NULL;
1325     proto_tree  *ie_tree = NULL;
1326     guint8 ie_len;
1327
1328     ie_len = tvb_get_guint8(tvb,offset+1);
1329     item = proto_tree_add_item(tree, hf_bssap_ptmsi_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1330     ie_tree = proto_item_add_subtree(item, ett_bssap_ptmsi);
1331
1332     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1333     offset++;
1334     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1335     offset++;
1336     /* The PTMSI consists of 4 octets. It can be coded using a full hexadecimal representation
1337      * (see 3GPP TS 23.003).
1338      */
1339     proto_tree_add_item(ie_tree, hf_bssap_ptmsi, tvb, offset, ie_len, ENC_BIG_ENDIAN);
1340
1341     return offset + ie_len;
1342
1343 }
1344 /* 18.4.21 Reject cause */
1345 static int
1346 dissect_bssap_reject_cause(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset)
1347 {
1348     proto_item  *item = NULL;
1349     proto_tree  *ie_tree = NULL;
1350     guint8 ie_len;
1351
1352     ie_len = tvb_get_guint8(tvb,offset+1);
1353     item = proto_tree_add_item(tree, hf_bssap_reject_cause_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1354     ie_tree = proto_item_add_subtree(item, ett_bssap_reject_cause);
1355
1356     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1357     offset++;
1358     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1359     offset++;
1360     /*  The rest of the information element is coded as the value part of
1361      *  the reject cause IE defined in 3GPP TS 24.008, not including
1362      *  3GPP TS 24.008 IEI.
1363      */
1364     de_rej_cause(tvb, ie_tree, pinfo, offset, ie_len, NULL, 0);
1365
1366     return offset + ie_len;
1367
1368 }
1369
1370 /* 18.4.21b Service Area Identification */
1371 static int
1372 dissect_bssap_service_area_id(tvbuff_t *tvb, proto_tree *tree, int offset)
1373 {
1374     proto_item  *item = NULL;
1375     proto_tree  *ie_tree = NULL;
1376     guint8 ie_len;
1377
1378     ie_len = tvb_get_guint8(tvb,offset+1);
1379     item = proto_tree_add_item(tree, hf_bssap_service_area_id_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1380     ie_tree = proto_item_add_subtree(item, ett_bssap_service_area_id);
1381
1382     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1383     offset++;
1384     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1385     offset++;
1386     /*  The rest of the information element is coded as the the value part
1387      *  of the SAI IE defined in 3GPP TS 25.413 (not including
1388      *  3GPP TS 25.413 IEI and 3GPP TS 25.413 length indicator).
1389      */
1390     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_data, tvb, offset, ie_len, ENC_BIG_ENDIAN);
1391
1392     return offset + ie_len;
1393
1394 }
1395
1396 /* 18.4.22 SGSN number */
1397
1398 static const true_false_string bssap_extension_value = {
1399   "No Extension",
1400   "Extension"
1401 };
1402
1403 static int
1404 dissect_bssap_sgsn_number(tvbuff_t *tvb, proto_tree *tree, int offset)
1405 {
1406     proto_item *item = NULL;
1407     proto_tree *ie_tree = NULL;
1408     guint8 ie_len;
1409     tvbuff_t *number_tvb;
1410     const char *digit_str;
1411
1412     ie_len = tvb_get_guint8(tvb,offset+1);
1413     item = proto_tree_add_item(tree, hf_bssap_sgsn_nr_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1414     ie_tree = proto_item_add_subtree(item, ett_bssap_sgsn_nr);
1415
1416     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1417     offset++;
1418     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1419     offset++;
1420     /* The SGSN number is coded as a sequence of TBCD digits (as specified in 3GPP TS 29.002),
1421      * compressed two into each octet. The Number is in international E.164 format as indicated by Octet 3
1422      * which coding is specified in 3GPP TS 29.002. This is a variable length information element,
1423      * and includes a length indicator. The value part of the SGSN number information element
1424      * (not including IEI, Length indicator and Octet 3) shall not exceed 15 digits.
1425      */
1426     proto_tree_add_item(ie_tree, hf_bssap_extension, tvb, offset, 1, ENC_BIG_ENDIAN);
1427     proto_tree_add_item(ie_tree, hf_bssap_type_of_number, tvb, offset, 1, ENC_BIG_ENDIAN);
1428     proto_tree_add_item(ie_tree, hf_bssap_numbering_plan_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1429     offset++;
1430     number_tvb = tvb_new_subset(tvb, offset, ie_len-1,ie_len-1);
1431     digit_str = unpack_digits(number_tvb, 0, &Dgt1_9_bcd, ENC_BIG_ENDIAN);
1432     proto_tree_add_string(ie_tree, hf_bssap_sgsn_number, number_tvb, 0, -1, digit_str);
1433
1434
1435     return offset + ie_len-1;
1436
1437 }
1438 /* 18.4.23 TMSI */
1439 static int
1440 dissect_bssap_tmsi(tvbuff_t *tvb, proto_tree *tree, int offset)
1441 {
1442     proto_item  *item = NULL;
1443     proto_tree  *ie_tree = NULL;
1444     guint8 ie_len;
1445
1446     ie_len = tvb_get_guint8(tvb,offset+1);
1447     item = proto_tree_add_item(tree, hf_bssap_tmsi_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1448     ie_tree = proto_item_add_subtree(item, ett_bssap_tmsi);
1449
1450     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1451     offset++;
1452     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1453     offset++;
1454     /* The TMSI consists of 4 octets. It can be coded using a full hexadecimal representation
1455      * (see 3GPP TS 23.003).
1456      */
1457     proto_tree_add_item(ie_tree, hf_bssap_tmsi, tvb, offset, ie_len, ENC_BIG_ENDIAN);
1458
1459
1460     return offset + ie_len;
1461
1462 }
1463
1464 /* 18.4.24 TMSI status */
1465 static const true_false_string bssap_tmsi_flag = {
1466   "Valid TMSI available",
1467   "No valid TMSI available"
1468 };
1469 static int
1470 dissect_bssap_tmsi_status(tvbuff_t *tvb, proto_tree *tree, int offset)
1471 {
1472     proto_item  *item = NULL;
1473     proto_tree  *ie_tree = NULL;
1474     guint8 ie_len;
1475
1476     ie_len = tvb_get_guint8(tvb,offset+1);
1477     item = proto_tree_add_item(tree, hf_bssap_tmsi_status_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1478     ie_tree = proto_item_add_subtree(item, ett_bssap_tmsi_status);
1479
1480     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1481     offset++;
1482     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1483     offset++;
1484     /* TMSI flag (octet 3) */
1485     proto_tree_add_item(ie_tree, hf_bssap_tmsi_status, tvb, offset, ie_len, ENC_BIG_ENDIAN);
1486
1487
1488     return offset + ie_len;
1489
1490 }
1491 /* 18.4.25 Uplink Tunnel Payload Control and Info */
1492 static const true_false_string bssap_E_flag = {
1493   "SGSN received the payload in ciphered",
1494   "SGSN did not receive the payload in ciphered form"
1495 };
1496 /* 3GPP TS 44.064 B.1.1 TOM Protocol Discriminator */
1497 static const value_string bssap_tom_prot_disc_values[] = {
1498     { 0x00,     "Not specified" },
1499     { 0x01,     "TIA/EIA-136" },
1500     { 0x02,     "RRLP" },
1501     { 0x03,     "Reserved for extension" },
1502     { 0,                NULL }
1503 };
1504 static int
1505 dissect_bssap_ulink_tunnel_payload_control_and_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1506 {
1507     proto_item  *item = NULL;
1508     proto_tree  *ie_tree = NULL;
1509     tvbuff_t *next_tvb;
1510     guint8 ie_len;
1511     guint8 octet;
1512     guint8 prot_disc;
1513
1514     ie_len = tvb_get_guint8(tvb,offset+1);
1515     item = proto_tree_add_item(tree, hf_bssap_ulink_tnl_pld_cntrl_amd_inf_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1516     ie_tree = proto_item_add_subtree(item, ett_bssap_ulink_tnl_pld_cntrl_amd_inf);
1517
1518     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1519     offset++;
1520     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1521     offset++;
1522     /* octet 3 bit 8 Spare */
1523     /* octet 3 bit 7 - 4
1524      * TOM Protocol Discriminator: Identifies the protocol using tunnelling of non-GSM signalling.
1525      * For coding, see 3GPP TS 44.064.
1526      */
1527     proto_tree_add_item(ie_tree, hf_bssap_tom_prot_disc, tvb, offset, 1, ENC_BIG_ENDIAN);
1528     octet = tvb_get_guint8(tvb,offset);
1529     prot_disc = (octet&0x78)>>3;
1530
1531     /* octet 3 bit 3 E: Cipher Request. When set to 1 indicates that the SGSN received the payload in ciphered form,
1532      * when set to 0 indicates that the SGSN did not receive the payload in ciphered form.
1533      */
1534     proto_tree_add_item(ie_tree, hf_bssap_e_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
1535
1536     /* octet 3 bit 2 - 1
1537      * Tunnel Priority: Indicates the priority of the Tunnel Payload. For coding, see Table 20.1: Association
1538      * between Tunnel Priority and LLC SAPs.
1539      */
1540     proto_tree_add_item(ie_tree, hf_bssap_tunnel_prio, tvb, offset, 1, ENC_BIG_ENDIAN);
1541     /* Tunnel payload */
1542     next_tvb = tvb_new_subset(tvb, offset, ie_len-4, ie_len-4);
1543
1544     if ((prot_disc == 2)&&(rrlp_handle))
1545         call_dissector(rrlp_handle, next_tvb, pinfo, ie_tree);
1546     else
1547         call_dissector(data_handle, next_tvb, pinfo, ie_tree);
1548
1549     return offset + ie_len;
1550
1551 }
1552
1553 /* 18.4.26 VLR number */
1554 static int
1555 dissect_bssap_vlr_number(tvbuff_t *tvb, proto_tree *tree, int offset)
1556 {
1557     proto_item *item = NULL;
1558     proto_tree *ie_tree = NULL;
1559     guint8 ie_len;
1560     tvbuff_t *number_tvb;
1561     const char *digit_str;
1562
1563     ie_len = tvb_get_guint8(tvb,offset+1);
1564     item = proto_tree_add_item(tree, hf_bssap_vlr_number_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1565     ie_tree = proto_item_add_subtree(item, ett_bssap_vlr_number);
1566
1567     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1568     offset++;
1569     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1570     offset++;
1571     /*  The VLR number is coded as a sequence of TBCD digits (as specified in 3GPP TS 29.002),
1572      *  compressed two into each octet. The Number is in international E.164 format as indicated by Octet 3
1573      *  which coding is specified in 3GPP TS 29.002. This is a variable length information element,
1574      *  and includes a length indicator. The value part of the VLR number information element
1575      *  (not including IEI, length indicator and Octet 3), shall not exceed 15 digits.
1576      */
1577
1578     proto_tree_add_item(ie_tree, hf_bssap_extension, tvb, offset, 1, ENC_BIG_ENDIAN);
1579     proto_tree_add_item(ie_tree, hf_bssap_type_of_number, tvb, offset, 1, ENC_BIG_ENDIAN);
1580     proto_tree_add_item(ie_tree, hf_bssap_numbering_plan_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1581     offset++;
1582     number_tvb = tvb_new_subset(tvb, offset, ie_len-1,ie_len-1);
1583     digit_str = unpack_digits(number_tvb, 0, &Dgt1_9_bcd, ENC_BIG_ENDIAN);
1584     proto_tree_add_string(ie_tree, hf_bssap_sgsn_number, number_tvb, 0, -1, digit_str);
1585
1586     return offset + ie_len-1;
1587
1588 }
1589 /* 18.4.27 Global CN-Id */
1590 static int
1591 dissect_bssap_global_cn_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1592 {
1593     proto_item  *item = NULL;
1594     proto_tree  *ie_tree = NULL;
1595     proto_item  *plmn_item = NULL;
1596     proto_tree  *plmn_tree = NULL;
1597     proto_item  *global_cn_id_item = NULL;
1598     proto_tree  *global_cn_id_tree = NULL;
1599     guint8 ie_len;
1600
1601     ie_len = tvb_get_guint8(tvb,offset+1);
1602     item = proto_tree_add_item(tree, hf_bssap_global_cn_id_ie, tvb, offset, ie_len+2, ENC_BIG_ENDIAN);
1603     ie_tree = proto_item_add_subtree(item, ett_bssap_global_cn);
1604
1605     proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1606     offset++;
1607     proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1608     offset++;
1609     /* The Global CN-Id consists of a PLMN-Id and a CN-Id, see 3GPP TS 23.003.
1610      *  The PLMN-Id consists of MCC and MNC coded according to Location Area Identification
1611      * in 3GPP TS 24.008. The CN-Id is an integer defined by O&M.
1612      * The least significant bit of the CN-Id field is bit 1 of octet 7 and
1613      * the most significant bit is bit 8 of octet 6. If the CN-Id does not fill the field reserved for it,
1614      * the rest of the bits are set to '0'.
1615      */
1616     global_cn_id_item = proto_tree_add_item(ie_tree, hf_bssap_global_cn_id, tvb, offset, ie_len, ENC_BIG_ENDIAN);
1617     global_cn_id_tree = proto_item_add_subtree(global_cn_id_item, ett_bssap_global_cn_id);
1618     /* Octet 3 - 5 PLMN-Id Coded as octets 2 to 4 of the Location Area Identification IE,
1619      * defined in 3GPP TS 24.008 (not including 3GPP TS 24.008 IEI and LAC).
1620      */
1621     plmn_item = proto_tree_add_item(global_cn_id_tree, hf_bssap_plmn_id, tvb, offset, 3, ENC_BIG_ENDIAN);
1622     plmn_tree = proto_item_add_subtree(plmn_item, ett_bssap_plmn);
1623     dissect_e212_mcc_mnc(tvb, pinfo, plmn_tree, offset, TRUE);
1624     offset = offset + 3;
1625
1626     /* Octet 6 - 7 CN-Id (INTEGER 0..4095) */
1627     proto_tree_add_item(global_cn_id_tree, hf_bssap_cn_id, tvb, offset, 2, ENC_BIG_ENDIAN);
1628     offset = offset+2;
1629
1630     return offset;
1631
1632 }
1633
1634 static void dissect_bssap_plus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1635 {
1636     proto_item  *bssap_item;
1637     proto_tree  *bssap_tree = NULL;
1638     guint8      message_type;
1639     int         offset = 0;
1640
1641     /*
1642      * Make entry in the Protocol column on summary display
1643      */
1644     col_set_str(pinfo->cinfo, COL_PROTOCOL, "BSSAP+");
1645
1646     if (pinfo->sccp_info && pinfo->sccp_info->data.co.assoc)
1647         pinfo->sccp_info->data.co.assoc->payload = SCCP_PLOAD_BSSAP;
1648
1649     /* create the BSSAP+ protocol tree */
1650     bssap_item = proto_tree_add_item(tree, proto_bssap, tvb, 0, -1, ENC_BIG_ENDIAN);
1651     bssap_tree = proto_item_add_subtree(bssap_item, ett_bssap);
1652
1653     message_type = tvb_get_guint8(tvb,offset);
1654     proto_tree_add_item(bssap_tree, hf_bssap_plus_message_type, tvb, offset, 1,ENC_BIG_ENDIAN);
1655     offset++;
1656
1657     col_add_str(pinfo->cinfo,COL_INFO, val_to_str(message_type,bssap_plus_message_type_values,"Unknown %u"));
1658
1659     switch(message_type){
1660     case BSSAP_PAGING_REQUEST:
1661         /* IMSI IMSI 18.4.10 M TLV 6-10 */
1662         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
1663             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1664
1665         /* VLR number VLR number 18.4.26 M TLV 5-11 */
1666         if ( check_ie(tvb, tree, &offset, BSSAP_VLR_NUMBER))
1667             offset = dissect_bssap_vlr_number(tvb, bssap_tree, offset);
1668
1669         /* End of mandatory elements */
1670         if (tvb_length_remaining(tvb,offset) == 0)
1671             return;
1672
1673         /* TMSI TMSI 18.4.23 O TLV 6 */
1674         if ( check_optional_ie(tvb, offset, BSSAP_TMSI))
1675             offset = dissect_bssap_tmsi(tvb, bssap_tree, offset);
1676         if (tvb_length_remaining(tvb,offset) == 0)
1677             return;
1678
1679         /* Location area identifier Location area identifier 18.4.14 O TLV 7 */
1680         if ( check_optional_ie(tvb, offset, BSSAP_LOC_AREA_ID))
1681             offset = dissect_bssap_loc_area_id(tvb, bssap_tree, pinfo, offset);
1682         if (tvb_length_remaining(tvb,offset) == 0)
1683             return;
1684
1685         /* Channel needed Channel needed 18.4.2 O TLV 3 */
1686         if ( check_optional_ie(tvb, offset, BSSAP_CHANNEL_NEEDED))
1687             offset = dissect_bssap_channel_needed(tvb, bssap_tree, pinfo, offset);
1688         if (tvb_length_remaining(tvb,offset) == 0)
1689             return;
1690
1691         /* eMLPP Priority eMLPP Priority 18.4.4 O TLV 3 */
1692         if ( check_optional_ie(tvb, offset, BSSAP_EMLPP_PRIORITY))
1693             offset = dissect_bssap_emlpp_priority(tvb, bssap_tree, offset);
1694         if (tvb_length_remaining(tvb,offset) == 0)
1695             return;
1696
1697         /* Global CN-Id Global CN-Id 18.4.27 O TLV 7 */
1698         if ( check_optional_ie(tvb, offset, BSSAP_GLOBAL_CN_ID))
1699             offset = dissect_bssap_global_cn_id(tvb, pinfo, bssap_tree, offset);
1700         if (tvb_length_remaining(tvb,offset) == 0)
1701             return;
1702
1703         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1704         break;
1705     case BSSAP_PAGING_REJECT:                   /*  17.1.18 */
1706         /* IMSI IMSI 18.4.10 M TLV 6-10 */
1707         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
1708             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1709         /* Gs Cause Gs Cause 18.4.7 M TLV 3 */
1710         if ( check_ie(tvb, tree, &offset, BSSAP_GS_CAUSE))
1711             offset = dissect_bssap_Gs_cause(tvb, bssap_tree, offset);
1712
1713         if (tvb_length_remaining(tvb,offset) == 0)
1714             return;
1715         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1716         break;
1717     case BSSAP_DOWNLINK_TUNNEL_REQUEST:         /*  17.1.4  */
1718         /* IMSI IMSI 18.4.10 M TLV 6-10 */
1719         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
1720             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1721
1722         /* VLR number VLR number 18.4.26 M TLV 5-11 */
1723         if ( check_ie(tvb, tree, &offset, BSSAP_VLR_NUMBER))
1724             offset = dissect_bssap_vlr_number(tvb, bssap_tree, offset);
1725
1726         /* Downlink Tunnel Payload Control and Info 18.4.3 M TLV 3-223 */
1727         if ( check_ie(tvb, tree, &offset, BSSAP_DLINK_TNL_PLD_CTR_AND_INF))
1728             offset = dissect_bssap_dlink_tunnel_payload_control_and_info(tvb, pinfo, bssap_tree, offset);
1729
1730         if (tvb_length_remaining(tvb,offset) == 0)
1731             return;
1732         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1733         break;
1734     case BSSAP_UPLINK_TUNNEL_REQUEST:           /*  17.1.23 */
1735         /* SGSN number 18.4.22 M TLV 5-11 */
1736         if ( check_ie(tvb, tree, &offset, BSSAP_SGSN_NUMBER))
1737             offset = dissect_bssap_sgsn_number(tvb, bssap_tree, offset);
1738
1739         /* Uplink Tunnel Payload Control and Info 18.4.25 M TLV 3-223 */
1740         if ( check_ie(tvb, tree, &offset, BSSAP_ULINK_TNL_PLD_CTR_AND_INF))
1741             offset = dissect_bssap_ulink_tunnel_payload_control_and_info(tvb, pinfo, bssap_tree, offset);
1742
1743         if (tvb_length_remaining(tvb,offset) == 0)
1744             return;
1745         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1746         break;
1747     case BSSAP_LOCATION_UPDATE_REQUEST:         /*  17.1.11 BSSAP+-LOCATION-UPDATE-REQUEST */
1748         /* IMSI IMSI 18.4.10 M TLV 6-10 */
1749         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
1750             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1751
1752         /* SGSN number SGSN number 18.4.22 M TLV 5-11 */
1753         if ( check_ie(tvb, tree, &offset, BSSAP_SGSN_NUMBER))
1754             offset = dissect_bssap_sgsn_number(tvb, bssap_tree, offset);
1755
1756         /* Update type GPRS location update type 18.4.6 M TLV 3 */
1757         if ( check_ie(tvb, tree, &offset, BSSAP_GPRS_LOC_UPD_TYPE))
1758             offset = dissect_bssap_gprs_location_update_type(tvb, bssap_tree, offset);
1759
1760         /* New Cell global identity Cell global identity 18.4.1 M TLV 10 */
1761         if ( check_ie(tvb, tree, &offset, BSSAP_CELL_GBL_ID))
1762             offset = dissect_bssap_cell_global_id(tvb, bssap_tree, pinfo, offset);
1763
1764         /* Mobile station classmark Mobile station classmark 1 18.4.18 M TLV 3 */
1765         if ( check_ie(tvb, tree, &offset, BSSAP_MOBILE_STN_CLS_MRK1))
1766             offset = dissect_bssap_mobile_stn_cls_mrk1(tvb, bssap_tree, pinfo, offset);
1767         if (tvb_length_remaining(tvb,offset) == 0)
1768             return;
1769
1770         /* Old location area identifier Location area identifier 18.4.14 O TLV 7 */
1771         if ( check_optional_ie(tvb, offset, BSSAP_LOC_AREA_ID))
1772             offset = dissect_bssap_loc_area_id(tvb, bssap_tree, pinfo, offset);
1773         if (tvb_length_remaining(tvb,offset) == 0)
1774             return;
1775
1776         /* TMSI status TMSI status 18.4.24 O TLV 3 */
1777         if ( check_optional_ie(tvb, offset, BSSAP_TMSI_STATUS))
1778             offset = dissect_bssap_tmsi_status(tvb, bssap_tree, offset);
1779         if (tvb_length_remaining(tvb,offset) == 0)
1780             return;
1781
1782         /* New service area identification Service area identification 18.4.21b O TLV 9 */
1783         if ( check_optional_ie(tvb, offset, BSSAP_SERVICE_AREA_ID))
1784             offset = dissect_bssap_service_area_id(tvb, bssap_tree, offset);
1785         if (tvb_length_remaining(tvb,offset) == 0)
1786             return;
1787
1788         /* IMEISV IMEISV 18.4.9 O TLV 10 */
1789         if ( check_optional_ie(tvb, offset, BSSAP_IMEISV))
1790             offset = dissect_bssap_imesiv(tvb, bssap_tree, offset);
1791         if (tvb_length_remaining(tvb,offset) == 0)
1792             return;
1793         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1794         break;
1795     case BSSAP_LOCATION_UPDATE_ACCEPT:          /*  17.1.9  */
1796         /* IMSI 18.4.10 M TLV 6-10 */
1797         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
1798             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1799
1800         /* Location area identifier Location area identifier 18.4.14 M TLV 7 */
1801         if ( check_ie(tvb, tree, &offset, BSSAP_LOC_AREA_ID))
1802             offset = dissect_bssap_loc_area_id(tvb, bssap_tree, pinfo, offset);
1803
1804         if (tvb_length_remaining(tvb,offset) == 0)
1805             return;
1806
1807         /* New TMSI, or IMSI Mobile identity 18.4.17 O TLV 6-10 */
1808         if ( check_optional_ie(tvb, offset, BSSAP_MOBILE_ID))
1809             offset = dissect_bssap_mobile_id(tvb, bssap_tree, pinfo, offset);
1810         if (tvb_length_remaining(tvb,offset) == 0)
1811             return;
1812         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1813         break;
1814     case BSSAP_LOCATION_UPDATE_REJECT:          /*  17.1.10 */
1815         /* IMSI IMSI 18.4.10 M TLV 6-10 */
1816         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
1817             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1818         /* Reject cause Reject cause 18.4.21 M TLV 3 */
1819         if ( check_ie(tvb, tree, &offset, BSSAP_REJECT_CAUSE))
1820             offset = dissect_bssap_reject_cause(tvb, bssap_tree, pinfo, offset);
1821         if (tvb_length_remaining(tvb,offset) == 0)
1822             return;
1823         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1824         break;
1825     case BSSAP_TMSI_REALLOCATION_COMPLETE:      /*  17.1.22 */
1826         /* IMSI IMSI 18.4.10 M TLV 6-10 */
1827         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
1828             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1829
1830         if (tvb_length_remaining(tvb,offset) == 0)
1831             return;
1832
1833         /* Cell global identity Cell global identity 18.4.1 O TLV 10 */
1834         if ( check_optional_ie(tvb, offset, BSSAP_CELL_GBL_ID))
1835             offset = dissect_bssap_cell_global_id(tvb, bssap_tree, pinfo, offset);
1836
1837         if (tvb_length_remaining(tvb,offset) == 0)
1838             return;
1839
1840         /* Service area identification Service area identification 18.4.21b O TLV 9 */
1841         if ( check_optional_ie(tvb, offset, BSSAP_SERVICE_AREA_ID))
1842             offset = dissect_bssap_service_area_id(tvb, bssap_tree, offset);
1843         if (tvb_length_remaining(tvb,offset) == 0)
1844             return;
1845         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1846         break;
1847     case BSSAP_ALERT_REQUEST:                   /*  17.1.3  */
1848         /* IMSI IMSI 18.4.10 M TLV 6-10 */
1849         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
1850             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1851
1852         if (tvb_length_remaining(tvb,offset) == 0)
1853             return;
1854         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1855         break;
1856     case BSSAP_ALERT_ACK:                       /*  17.1.1  */
1857         /* IMSI IMSI 18.4.10 M TLV 6-10 */
1858         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
1859             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1860
1861         if (tvb_length_remaining(tvb,offset) == 0)
1862             return;
1863         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1864         break;
1865     case BSSAP_ALERT_REJECT:                    /*  17.1.2  */
1866         /* IMSI IMSI 18.4.10 M TLV 6-10 */
1867         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
1868             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1869
1870         /* Gs Cause Gs Cause 18.4.7 M TLV 3 */
1871         if ( check_ie(tvb, tree, &offset, BSSAP_GS_CAUSE))
1872             offset = dissect_bssap_Gs_cause(tvb, bssap_tree, offset);
1873
1874         if (tvb_length_remaining(tvb,offset) == 0)
1875             return;
1876         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1877         break;
1878     case BSSAP_MS_ACTIVITY_INDICATION:          /*  17.1.14 */
1879         /* IMSI IMSI 18.4.10 M TLV 6-10 */
1880         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
1881             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1882
1883         if (tvb_length_remaining(tvb,offset) == 0)
1884             return;
1885
1886         /* Cell global identity Cell global identity 18.4.1 O TLV 10 */
1887         if ( check_optional_ie(tvb, offset, BSSAP_CELL_GBL_ID))
1888             offset = dissect_bssap_cell_global_id(tvb, bssap_tree, pinfo, offset);
1889
1890         if (tvb_length_remaining(tvb,offset) == 0)
1891             return;
1892
1893         /* Service area identification Service area identification 18.4.21b O TLV 9 */
1894         if ( check_optional_ie(tvb, offset, BSSAP_SERVICE_AREA_ID))
1895             offset = dissect_bssap_service_area_id(tvb, bssap_tree, offset);
1896         if (tvb_length_remaining(tvb,offset) == 0)
1897             return;
1898         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1899         break;
1900     case BSSAP_GPRS_DETACH_INDICATION:          /*  17.1.6  */
1901         /* IMSI IMSI 18.4.10 M TLV 6-10 */
1902         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
1903             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1904
1905         /* SGSN number SGSN number 18.4.22 M TLV 5-11 */
1906         if ( check_ie(tvb, tree, &offset, BSSAP_SGSN_NUMBER))
1907             offset = dissect_bssap_sgsn_number(tvb, bssap_tree, offset);
1908
1909         /* IMSI detach from GPRS service type IMSI detach from GPRS service type 18.4.17 M TLV 3 */
1910         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI_DET_FROM_GPRS_SERV_TYPE))
1911             offset = dissect_bssap_imsi_det_from_gprs_serv_type(tvb, bssap_tree, offset);
1912
1913         if (tvb_length_remaining(tvb,offset) == 0)
1914             return;
1915
1916         /* Cell global identity Cell global identity 18.4.1 O TLV 10 */
1917         if ( check_optional_ie(tvb, offset, BSSAP_CELL_GBL_ID))
1918             offset = dissect_bssap_cell_global_id(tvb, bssap_tree, pinfo, offset);
1919
1920         if (tvb_length_remaining(tvb,offset) == 0)
1921             return;
1922
1923         /* Service area identification Service area identification 18.4.21b O TLV 9 */
1924         if ( check_optional_ie(tvb, offset, BSSAP_SERVICE_AREA_ID))
1925             offset = dissect_bssap_service_area_id(tvb, bssap_tree, offset);
1926         if (tvb_length_remaining(tvb,offset) == 0)
1927             return;
1928         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1929         break;
1930     case BSSAP_GPRS_DETACH_ACK:                 /*  17.1.5  */
1931         /* IMSI IMSI 18.4.10 M TLV 6-10 */
1932         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
1933             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1934
1935         if (tvb_length_remaining(tvb,offset) == 0)
1936             return;
1937         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1938         break;
1939     case BSSAP_IMSI_DETACH_INDICATION:          /*  17.1.8  */
1940         /* IMSI IMSI 18.4.10 M TLV 6-10 */
1941         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
1942             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1943
1944         /* SGSN number SGSN number 18.4.22 M TLV 5-11 */
1945         if ( check_ie(tvb, tree, &offset, BSSAP_SGSN_NUMBER))
1946             offset = dissect_bssap_sgsn_number(tvb, bssap_tree, offset);
1947
1948         /* Detach type IMSI detach from non-GPRS service type 18.4.11 M TLV 3 */
1949         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI_DET_FROM_NON_GPRS_SERV_TYPE))
1950             offset = dissect_bssap_imsi_det_from_non_gprs_serv_type(tvb, bssap_tree, offset);
1951
1952         if (tvb_length_remaining(tvb,offset) == 0)
1953             return;
1954
1955         /* Cell global identity Cell global identity 18.4.1 O TLV 10 */
1956         if ( check_optional_ie(tvb, offset, BSSAP_CELL_GBL_ID))
1957             offset = dissect_bssap_cell_global_id(tvb, bssap_tree, pinfo, offset);
1958
1959         if (tvb_length_remaining(tvb,offset) == 0)
1960             return;
1961
1962         /* Location information age Location information age 18.4.14 O TLV 4 */
1963         if ( check_optional_ie(tvb, offset, BSSAP_LOC_INF_AGE))
1964             offset = dissect_bssap_location_information_age(tvb, bssap_tree, offset);
1965
1966         if (tvb_length_remaining(tvb,offset) == 0)
1967             return;
1968
1969         /* Service area identification Service area identification 18.4.21b O TLV 9 */
1970         if ( check_optional_ie(tvb, offset, BSSAP_SERVICE_AREA_ID))
1971             offset = dissect_bssap_service_area_id(tvb, bssap_tree, offset);
1972         if (tvb_length_remaining(tvb,offset) == 0)
1973             return;
1974         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1975         break;
1976     case BSSAP_IMSI_DETACH_ACK:                 /*  17.1.7  */
1977         /* IMSI IMSI 18.4.10 M TLV 6-10 */
1978         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
1979             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1980
1981         if (tvb_length_remaining(tvb,offset) == 0)
1982             return;
1983         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1984         break;
1985     case BSSAP_RESET_INDICATION:                /*  17.1.21 */
1986         /* Conditional IE:s */
1987         /* SGSN number SGSN number 18.4.22 C TLV 5-11 */
1988         if ( check_optional_ie(tvb, offset, BSSAP_SGSN_NUMBER)){
1989             offset = dissect_bssap_sgsn_number(tvb, bssap_tree, offset);
1990             if (tvb_length_remaining(tvb,offset) == 0)
1991                 return;
1992             proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1993         }else{
1994             /* VLR number VLR number 18.4.26 C TLV 5-11 */
1995             if ( check_optional_ie(tvb, offset, BSSAP_VLR_NUMBER)){
1996                 offset = dissect_bssap_vlr_number(tvb, bssap_tree, offset);
1997                 if (tvb_length_remaining(tvb,offset) == 0)
1998                     return;
1999                 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
2000             }
2001         }
2002         proto_tree_add_text(tree, tvb, offset, -1, "Conditional IE");
2003         break;
2004     case BSSAP_RESET_ACK:                       /*  17.1.20 */
2005         /* Conditional IE:s */
2006         /* SGSN number SGSN number 18.4.22 C TLV 5-11 */
2007         if ( check_optional_ie(tvb, offset, BSSAP_SGSN_NUMBER)){
2008             offset = dissect_bssap_sgsn_number(tvb, bssap_tree, offset);
2009             if (tvb_length_remaining(tvb,offset) == 0)
2010                 return;
2011             proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
2012         }else{
2013             /* VLR number VLR number 18.4.26 C TLV 5-11 */
2014             if ( check_optional_ie(tvb, offset, BSSAP_VLR_NUMBER)){
2015                 offset = dissect_bssap_vlr_number(tvb, bssap_tree, offset);
2016                 if (tvb_length_remaining(tvb,offset) == 0)
2017                     return;
2018                 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
2019             }
2020         }
2021         proto_tree_add_text(tree, tvb, offset, -1, "Conditional IE");
2022         break;
2023     case BSSAP_MS_INFORMATION_REQUEST:          /*  17.1.15 */
2024         /* IMSI IMSI 18.4.10 M TLV 6-10 */
2025         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
2026             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
2027
2028         /* Information requested Information requested 18.4.13 M TLV 3 */
2029         if ( check_ie(tvb, tree, &offset, BSSAP_INFO_REQ))
2030             offset = dissect_bssap_info_req(tvb, bssap_tree, offset);
2031
2032         if (tvb_length_remaining(tvb,offset) == 0)
2033             return;
2034
2035         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
2036         break;
2037     case BSSAP_MS_INFORMATION_RESPONSE:         /*  17.1.16 */
2038         /* IMSI IMSI 18.4.10 M TLV 6-10 */
2039         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
2040             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
2041         if (tvb_length_remaining(tvb,offset) == 0)
2042             return;
2043
2044         /* TMSI TMSI 18.4.23 O TLV 6 */
2045         if ( check_optional_ie(tvb, offset, BSSAP_TMSI))
2046             offset = dissect_bssap_tmsi(tvb, bssap_tree, offset);
2047         if (tvb_length_remaining(tvb,offset) == 0)
2048             return;
2049
2050         /* PTMSI PTMSI 18.4.20 O TLV 6 BSSAP_PTMSI*/
2051         if ( check_optional_ie(tvb, offset, BSSAP_PTMSI))
2052             offset = dissect_bssap_ptmsi(tvb, bssap_tree, offset);
2053         if (tvb_length_remaining(tvb,offset) == 0)
2054             return;
2055
2056         /* IMEI IMEI 18.4.8 O TLV 10 */
2057         if ( check_optional_ie(tvb, offset, BSSAP_IMEI))
2058             offset = dissect_bssap_imei(tvb, bssap_tree, offset);
2059         if (tvb_length_remaining(tvb,offset) == 0)
2060             return;
2061         /* IMEISV IMEISV 18.4.9 O TLV 10 BSSAP_IMEISV*/
2062         if ( check_optional_ie(tvb, offset, BSSAP_IMEISV))
2063             offset = dissect_bssap_imesiv(tvb, bssap_tree, offset);
2064         if (tvb_length_remaining(tvb,offset) == 0)
2065             return;
2066
2067         /* Cell global identity Cell global identity 18.4.1 O TLV 10 */
2068         if ( check_optional_ie(tvb, offset, BSSAP_CELL_GBL_ID))
2069             offset = dissect_bssap_cell_global_id(tvb, bssap_tree, pinfo, offset);
2070
2071         if (tvb_length_remaining(tvb,offset) == 0)
2072             return;
2073         /* Location information age Location information age 18.4.15 O TLV 4 */
2074         if ( check_optional_ie(tvb, offset, BSSAP_LOC_INF_AGE))
2075             offset = dissect_bssap_location_information_age(tvb, bssap_tree, offset);
2076
2077         if (tvb_length_remaining(tvb,offset) == 0)
2078             return;
2079
2080         /* Mobile station state Mobile station state 18.4.19 O TLV 3 */
2081         if ( check_optional_ie(tvb, offset, BSSAP_MOBILE_STN_STATE))
2082             offset = dissect_bssap_mobile_station_state(tvb, bssap_tree, offset);
2083
2084         if (tvb_length_remaining(tvb,offset) == 0)
2085             return;
2086
2087         /* Service area identification Service area identification 18.4.21b O TLV 9 */
2088         if ( check_optional_ie(tvb, offset, BSSAP_SERVICE_AREA_ID))
2089             offset = dissect_bssap_service_area_id(tvb, bssap_tree, offset);
2090         if (tvb_length_remaining(tvb,offset) == 0)
2091             return;
2092         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
2093         break;
2094     case BSSAP_MM_INFORMATION_REQUEST:          /*  17.1.12 */
2095         /* IMSI IMSI 18.4.10 M TLV 6-10 */
2096         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
2097             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
2098
2099         if (tvb_length_remaining(tvb,offset) == 0)
2100             return;
2101         /* MM information MM information 18.4.16 O TLV 3-n */
2102         if ( check_optional_ie(tvb, offset, BSSAP_MM_INFORMATION))
2103             offset = dissect_bssap_MM_information(tvb, bssap_tree, pinfo, offset);
2104         if (tvb_length_remaining(tvb,offset) == 0)
2105             return;
2106         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
2107         break;
2108     case BSSAP_MOBILE_STATUS:                   /*  17.1.13 */
2109         /* IMSI IMSI 18.4.10 O TLV 6-10 */
2110         if ( check_optional_ie(tvb, offset, BSSAP_IMSI))
2111                 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
2112         /* Gs Cause Gs Cause 18.4.7 M TLV 3 */
2113         if ( check_ie(tvb, tree, &offset, BSSAP_GS_CAUSE))
2114             offset = dissect_bssap_Gs_cause(tvb, bssap_tree, offset);
2115
2116         /* Erroneous message Erroneous message 18.4.5 M TLV 3-n BSSAP_ERRONEOUS_MSG*/
2117         if ( check_ie(tvb, tree, &offset, BSSAP_ERRONEOUS_MSG))
2118             offset = dissect_bssap_gprs_erroneous_msg(tvb, bssap_tree, offset);
2119
2120         if (tvb_length_remaining(tvb,offset) == 0)
2121             return;
2122         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
2123         break;
2124     case BSSAP_MS_UNREACHABLE:                  /*  17.1.17 */
2125         /* IMSI IMSI 18.4.10 M TLV 6-10 */
2126         if ( check_ie(tvb, tree, &offset, BSSAP_IMSI))
2127             offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
2128
2129         /* Gs Cause Gs Cause 18.4.7 M TLV 3 */
2130         if ( check_ie(tvb, tree, &offset, BSSAP_GS_CAUSE))
2131             offset = dissect_bssap_Gs_cause(tvb, bssap_tree, offset);
2132
2133         if (tvb_length_remaining(tvb,offset) == 0)
2134             return;
2135         proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
2136         break;
2137     default:
2138         break;
2139     }
2140 }
2141
2142 static gboolean
2143 dissect_bssap_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2144 {
2145     /* Is it a BSSAP/BSAP packet?
2146      *    If octet_1 == 0x00 and octet_2 == length(tvb) - 2
2147      * or if octet_1 == 0x01 and octet_3 == length(tvb) - 3
2148      * then we'll assume it is a bssap packet
2149      *    If octet_1 == 0x00 a further check is done
2150      *    to differentiate a BSSMAP BLOCK message from a
2151      *    RANAP DirectTransfer (under certain conditions)
2152      */
2153     switch (tvb_get_guint8(tvb, 0))
2154     {
2155     case 0x00:
2156         if (tvb_get_guint8(tvb, 1) != (tvb_length(tvb) - 2)) { return(ENC_BIG_ENDIAN); }
2157         if (tvb_get_guint8(tvb, 2) == 0x40 && tvb_get_guint8(tvb, 3) != 0x01) {
2158             return(ENC_BIG_ENDIAN); }
2159         break;
2160
2161     case 0x01:
2162         if (tvb_get_guint8(tvb, 2) != (tvb_length(tvb) - 3)) { return(ENC_BIG_ENDIAN); }
2163         break;
2164
2165     default:
2166         return(ENC_BIG_ENDIAN);
2167     }
2168
2169     dissect_bssap(tvb, pinfo, tree);
2170
2171     return(TRUE);
2172 }
2173
2174 /* Register the protocol with Wireshark */
2175 void
2176 proto_register_bssap(void)
2177 {
2178     module_t    *bssap_module;
2179
2180     /* Setup list of header fields */
2181     static hf_register_info hf[] = {
2182         { &hf_bssap_pdu_type,
2183           { "Message Type", "bssap.pdu_type",
2184         FT_UINT8, BASE_HEX, VALS(bssap_pdu_type_values), 0x0,
2185         NULL, HFILL}},
2186         { &hf_bsap_pdu_type,
2187           { "Message Type", "bsap.pdu_type",
2188         FT_UINT8, BASE_HEX, VALS(bsap_pdu_type_values), 0x0,
2189         NULL, HFILL}},
2190         { &hf_bssap_dlci_cc,
2191           { "Control Channel", "bssap.dlci.cc",
2192         FT_UINT8, BASE_HEX, VALS(bssap_cc_values), CC_MASK,
2193         NULL, HFILL}},
2194         { &hf_bsap_dlci_cc,
2195           { "Control Channel", "bsap.dlci.cc",
2196         FT_UINT8, BASE_HEX, VALS(bsap_cc_values), CC_MASK,
2197         NULL, HFILL}},
2198         { &hf_bssap_dlci_spare,
2199           { "Spare", "bssap.dlci.spare",
2200         FT_UINT8, BASE_HEX, NULL, SPARE_MASK,
2201         NULL, HFILL}},
2202         { &hf_bsap_dlci_rsvd,
2203           { "Reserved", "bsap.dlci.rsvd",
2204         FT_UINT8, BASE_HEX, NULL, SPARE_MASK,
2205         NULL, HFILL}},
2206         { &hf_bssap_dlci_sapi,
2207           { "SAPI", "bssap.dlci.sapi",
2208         FT_UINT8, BASE_HEX, VALS(bssap_sapi_values), SAPI_MASK,
2209         NULL, HFILL}},
2210         { &hf_bsap_dlci_sapi,
2211           { "SAPI", "bsap.dlci.sapi",
2212         FT_UINT8, BASE_HEX, VALS(bsap_sapi_values), SAPI_MASK,
2213         NULL, HFILL}},
2214         { &hf_bssap_length,
2215           { "Length", "bssap.length",
2216         FT_UINT8, BASE_DEC, NULL, 0x0,
2217         NULL, HFILL}},
2218
2219         { &hf_bssap_plus_message_type,
2220           { "Message Type", "bssap_plus.msg_type",
2221         FT_UINT8, BASE_DEC, VALS(bssap_plus_message_type_values), 0x0,
2222         NULL, HFILL}},
2223         { &hf_bssap_plus_ie,
2224           { "IEI", "bssap_plus.iei",
2225         FT_UINT8, BASE_DEC, VALS(bssap_plus_ie_id_values), 0x0,
2226         NULL, HFILL}},
2227         { &hf_bssap_plus_ie_len,
2228           { "Length indicator", "bssap_plus.iei",
2229         FT_UINT8, BASE_DEC, NULL, 0x0,
2230         NULL, HFILL}},
2231         { &hf_bssap_extension,
2232           { "Extension", "bssap.extension",
2233             FT_BOOLEAN, 8, TFS(&bssap_extension_value), 0x80,
2234             NULL, HFILL }},
2235         { &hf_bssap_type_of_number,
2236           { "Type of number", "bssap.type_of_number",
2237             FT_UINT8, BASE_HEX, VALS(gsm_a_type_of_number_values), 0x70,
2238             NULL, HFILL }},
2239         { &hf_bssap_numbering_plan_id,
2240           { "Numbering plan identification", "bssap.number_plan",
2241             FT_UINT8, BASE_HEX, VALS(gsm_a_numbering_plan_id_values), 0x0f,
2242             NULL, HFILL }},
2243         { &hf_bssap_sgsn_number,
2244           { "SGSN number", "bssap.sgsn_number",
2245             FT_STRING, BASE_NONE, NULL, 0,
2246             NULL, HFILL }},
2247         { &hf_bssap_vlr_number,
2248           { "VLR number", "bssap.vlr_number",
2249             FT_STRING, BASE_NONE, NULL, 0,
2250             NULL, HFILL }},
2251         { &hf_bssap_cell_global_id_ie,
2252           { "Cell global identity IE", "bssap.cell_global_id_ie",
2253             FT_NONE, BASE_NONE, NULL, 0,
2254             NULL, HFILL }},
2255         { &hf_bssap_channel_needed_ie,
2256           { "Channel needed IE", "bssap.cell_global_id_ie",
2257             FT_NONE, BASE_NONE, NULL, 0,
2258             NULL, HFILL }},
2259         { &hf_bssap_dlink_tnl_pld_cntrl_amd_inf_ie,
2260           { "Downlink Tunnel Payload Control and Info IE", "bssap.dlink_tnl_pld_cntrl_amd_inf_ie",
2261             FT_NONE, BASE_NONE, NULL, 0,
2262             NULL, HFILL }},
2263         { &hf_bssap_ulink_tnl_pld_cntrl_amd_inf_ie,
2264           { "Uplink Tunnel Payload Control and Info IE", "bssap.ulink_tnl_pld_cntrl_amd_inf_ie",
2265             FT_NONE, BASE_NONE, NULL, 0,
2266             NULL, HFILL }},
2267         { &hf_bssap_emlpp_prio_ie,
2268           { "eMLPP Priority IE", "bssap.emlpp_prio_ie",
2269             FT_NONE, BASE_NONE, NULL, 0,
2270             NULL, HFILL }},
2271         { &hf_bssap_gprs_erroneous_msg_ie,
2272           { "Erroneous message IE", "bssap.erroneous_msg_ie",
2273             FT_NONE, BASE_NONE, NULL, 0,
2274             NULL, HFILL }},
2275         { &hf_bssap_gprs_loc_upd_type_ie,
2276           { "GPRS location update type IE", "bssap.loc_upd_type_ie",
2277             FT_NONE, BASE_NONE, NULL, 0,
2278             NULL, HFILL }},
2279         { &hf_bssap_Gs_cause_ie,
2280           { "Gs Cause IE", "bssap.Gs_cause_ie",
2281             FT_NONE, BASE_NONE, NULL, 0,
2282             NULL, HFILL }},
2283         { &hf_bssap_imei_ie,
2284           { "IMEI IE", "bssap.imei_ie",
2285             FT_NONE, BASE_NONE, NULL, 0,
2286             NULL, HFILL }},
2287         { &hf_bssap_imesiv_ie,
2288           { "IMEISV IE", "bssap.imesiv",
2289             FT_NONE, BASE_NONE, NULL, 0,
2290             NULL, HFILL }},
2291         { &hf_bssap_imsi_ie,
2292           { "IMSI IE", "bssap.imsi_ie",
2293             FT_NONE, BASE_NONE, NULL, 0,
2294             NULL, HFILL }},
2295         { &hf_bssap_imsi_det_from_gprs_serv_type_ie,
2296           { "IMSI detach from GPRS service type IE", "bssap.msi_det_from_gprs_serv_type_ie",
2297             FT_NONE, BASE_NONE, NULL, 0,
2298             NULL, HFILL }},
2299         { &hf_bssap_imsi_det_from_non_gprs_serv_type_ie,
2300           { "IMSI detach from non-GPRS service IE", "bssap.msi_det_from_non_gprs_serv_type_ie",
2301             FT_NONE, BASE_NONE, NULL, 0,
2302             NULL, HFILL }},
2303         { &hf_bssap_info_req_ie,
2304           { "Information requested IE", "bssap.info_req_ie",
2305             FT_NONE, BASE_NONE, NULL, 0,
2306             NULL, HFILL }},
2307         { &hf_bssap_loc_area_id_ie,
2308           { "Location area identifier IE", "bssap.loc_area_id_ie",
2309             FT_NONE, BASE_NONE, NULL, 0,
2310             NULL, HFILL }},
2311         { &hf_bssap_loc_inf_age_ie,
2312           { "Location information age IE", "bssap.loc_inf_age_ie",
2313             FT_NONE, BASE_NONE, NULL, 0,
2314             NULL, HFILL }},
2315         { &hf_bssap_mm_information_ie,
2316           { "MM information IE", "bssap.mm_information",
2317             FT_NONE, BASE_NONE, NULL, 0,
2318             NULL, HFILL }},
2319         { &hf_bssap_mobile_id_ie,
2320           { "Mobile identity IE", "bssap.mobile_id_ie",
2321             FT_NONE, BASE_NONE, NULL, 0,
2322             NULL, HFILL }},
2323         { &hf_bssap_mobile_stn_cls_mrk1_ie,
2324           { "Mobile station classmark 1 IE", "bssap.mobile_stn_cls_mrk1_ie",
2325             FT_NONE, BASE_NONE, NULL, 0,
2326             NULL, HFILL }},
2327         { &hf_bssap_mobile_station_state_ie,
2328           { "Mobile station state IE", "bssap.mobile_station_state_ie",
2329             FT_NONE, BASE_NONE, NULL, 0,
2330             NULL, HFILL }},
2331         { &hf_bssap_ptmsi_ie,
2332           { "PTMSI IE", "bssap.ptmsi_ie",
2333             FT_NONE, BASE_NONE, NULL, 0,
2334             NULL, HFILL }},
2335         { &hf_bssap_reject_cause_ie,
2336           { "Reject cause IE", "bssap.reject_cause_ie",
2337             FT_NONE, BASE_NONE, NULL, 0,
2338             NULL, HFILL }},
2339         { &hf_bssap_service_area_id_ie,
2340           { "Service area identification IE", "bssap.mobile_stn_cls_mrk1_ie",
2341             FT_NONE, BASE_NONE, NULL, 0,
2342             "Mobile station classmark 1", HFILL }},
2343         { &hf_bssap_sgsn_nr_ie,
2344           { "SGSN number IE", "bssap.imsi_ie",
2345             FT_NONE, BASE_NONE, NULL, 0,
2346             NULL, HFILL }},
2347         { &hf_bssap_tmsi_ie,
2348           { "TMSI IE", "bssap.tmsi_ie",
2349             FT_NONE, BASE_NONE, NULL, 0,
2350             NULL, HFILL }},
2351         { &hf_bssap_tmsi_status_ie,
2352           { "TMSI status IE", "bssap.tmsi_status_ie",
2353             FT_NONE, BASE_NONE, NULL, 0,
2354             NULL, HFILL }},
2355         { &hf_bssap_vlr_number_ie,
2356           { "VLR number IE", "bssap.vlr_number_ie",
2357             FT_NONE, BASE_NONE, NULL, 0,
2358             NULL, HFILL }},
2359         { &hf_bssap_global_cn_id_ie,
2360           { "Global CN-Id IE", "bssap.global_cn_id_ie",
2361             FT_NONE, BASE_NONE, NULL, 0,
2362             NULL, HFILL }},
2363
2364         { &hf_bssap_plus_ie_data,
2365           { "IE Data", "bssap.ie_data",
2366             FT_BYTES, BASE_NONE, NULL, 0,
2367             NULL, HFILL }},
2368
2369         { &hf_bssap_call_priority,
2370           { "eMLPP Priority", "bssap.gprs_loc_upd_type",
2371         FT_UINT8, BASE_DEC, VALS(bssap_call_priority_values), 0x07,
2372         NULL, HFILL}},
2373         { &hf_bssap_gprs_loc_upd_type,
2374           { "GPRS location update type", "bssap.gprs_loc_upd_type",
2375         FT_UINT8, BASE_DEC, VALS(bssap_plus_GPRS_loc_upd_type_values), 0x0,
2376         NULL, HFILL}},
2377         { &hf_bssap_Gs_cause,
2378           { "Gs cause", "bssap.gprs_loc_upd_type",
2379         FT_UINT8, BASE_DEC, VALS(bssap_Gs_cause_values), 0x0,
2380         NULL, HFILL}},
2381         { &hf_bssap_imei,
2382           { "IMEI", "bssap.imei",
2383             FT_STRING, BASE_NONE, NULL, 0,
2384             NULL, HFILL }},
2385         { &hf_bssap_imeisv,
2386           { "IMEISV", "bssap.imeisv",
2387             FT_STRING, BASE_NONE, NULL, 0,
2388             NULL, HFILL }},
2389         { &hf_bssap_imsi,
2390           { "IMSI", "bssap.imsi",
2391             FT_STRING, BASE_NONE, NULL, 0,
2392             NULL, HFILL }},
2393         { &hf_bssap_imsi_det_from_gprs_serv_type,
2394           { "IMSI detach from GPRS service type", "bssap.imsi_det_from_gprs_serv_type",
2395         FT_UINT8, BASE_DEC, VALS(bssap_Gs_cause_values), 0x0,
2396         NULL, HFILL}},
2397         { &hf_bssap_info_req,
2398           { "Information requested", "bssap.info_req",
2399         FT_UINT8, BASE_DEC, VALS(bssap_info_req_values), 0x0,
2400         NULL, HFILL}},
2401         { &hf_bssap_loc_inf_age,
2402           { "AgeOfLocationInformation in minutes", "bssap.loc_inf_age",
2403         FT_UINT16, BASE_DEC, NULL, 0x0,
2404         NULL, HFILL}},
2405         { &hf_bssap_mobile_station_state,
2406           { "Mobile station state", "bssap.mobile_station_state",
2407         FT_UINT8, BASE_DEC, VALS(bssap_mobile_station_state_values), 0x0,
2408         NULL, HFILL}},
2409         { &hf_bssap_ptmsi,
2410           { "PTMSI", "bssap.ptmsi",
2411         FT_BYTES, BASE_NONE, NULL, 0x0,
2412         NULL, HFILL}},
2413         { &hf_bssap_tmsi,
2414           { "TMSI", "bssap.tmsi",
2415         FT_BYTES, BASE_NONE, NULL, 0x0,
2416         NULL, HFILL}},
2417         { &hf_bssap_tmsi_status,
2418           { "TMSI status", "bssap.tmsi_status",
2419             FT_BOOLEAN, 8, TFS(&bssap_tmsi_flag), 0x01,
2420             NULL, HFILL }},
2421         { &hf_bssap_tom_prot_disc,
2422           { "TOM Protocol Discriminator", "bssap.Tom_prot_disc",
2423             FT_UINT8, BASE_DEC, VALS(bssap_tom_prot_disc_values), 0x78,
2424             NULL, HFILL}},
2425         { &hf_bssap_e_bit,
2426           { "E: Cipher Request", "bssap.tmsi_status",
2427             FT_BOOLEAN, 8, TFS(&bssap_E_flag), 0x04,
2428             NULL, HFILL }},
2429         { &hf_bssap_tunnel_prio,
2430           { "Tunnel Priority", "bssap.tunnel_prio",
2431         FT_UINT8, BASE_DEC, NULL, 0x0,
2432         NULL, HFILL}},
2433         { &hf_bssap_global_cn_id,
2434           { "Global CN-Id", "bssap.global_cn_id",
2435         FT_BYTES, BASE_NONE, NULL, 0x0,
2436         NULL, HFILL}},
2437         { &hf_bssap_plmn_id,
2438           { "PLMN-Id", "bssap.plmn_id",
2439         FT_BYTES, BASE_NONE, NULL, 0x0,
2440         NULL, HFILL}},
2441         { &hf_bssap_cn_id,
2442           { "CN-Id", "bssap.cn_id",
2443         FT_UINT16, BASE_DEC, NULL, 0x0,
2444         NULL, HFILL}},
2445         { &hf_bssap_cell_global_id,
2446           { "Cell global identity", "bssap.plmn_id",
2447         FT_BYTES, BASE_NONE, NULL, 0x0,
2448         NULL, HFILL}},
2449     };
2450
2451     /* Setup protocol subtree array */
2452     static gint *ett[] = {
2453         &ett_bssap,
2454         &ett_bssap_dlci,
2455         &ett_bssap_imsi,
2456         &ett_bssap_imsi_det_from_gprs_serv_type,
2457         &ett_bssap_imsi_det_from_non_gprs_serv_type,
2458         &ett_bssap_info_req,
2459         &ett_bssap_loc_area_id,
2460         &ett_bssap_loc_inf_age,
2461         &ett_bssap_mm_information,
2462         &ett_bssap_mobile_id,
2463         &ett_bssap_sgsn_nr,
2464         &ett_bssap_tmsi,
2465         &ett_bssap_tmsi_status,
2466         &ett_bssap_vlr_number,
2467         &ett_bssap_global_cn,
2468         &ett_bssap_gprs_loc_upd,
2469         &ett_bassp_Gs_cause,
2470         &ett_bassp_imei,
2471         &ett_bassp_imesiv,
2472         &ett_bssap_cell_global_id,
2473         &ett_bssap_cgi,
2474         &ett_bssap_channel_needed,
2475         &ett_bssap_dlink_tnl_pld_cntrl_amd_inf,
2476         &ett_bssap_ulink_tnl_pld_cntrl_amd_inf,
2477         &ett_bssap_emlpp_prio,
2478         &ett_bssap_erroneous_msg,
2479         &ett_bssap_mobile_stn_cls_mrk1,
2480         &ett_bssap_mobile_station_state,
2481         &ett_bssap_ptmsi,
2482         &ett_bssap_reject_cause,
2483         &ett_bssap_service_area_id,
2484         &ett_bssap_global_cn_id,
2485         &ett_bssap_plmn,
2486     };
2487
2488     static enum_val_t gsm_or_lb_interface_options[] = {
2489         { "gsm a",    "GSM A",    GSM_INTERFACE },
2490         { "lb",    "Lb",    LB_INTERFACE  },
2491         { NULL,        NULL,        0 }
2492     };
2493
2494     static enum_val_t bssap_or_bsap_options[] = {
2495         { "bssap",  "BSSAP",    BSSAP },
2496         { "bsap",   "BSAP",     BSAP  },
2497         { NULL,     NULL,       0 }
2498     };
2499
2500
2501     /* Register the protocol name and description */
2502     proto_bssap = proto_register_protocol("BSSAP/BSAP", "BSSAP", "bssap");
2503     /*proto_bssap_plus = proto_register_protocol("BSSAP2", "BSSAP2", "bssap2");*/
2504
2505     register_dissector("bssap", dissect_bssap, proto_bssap);
2506
2507     /* Required function calls to register the header fields and subtrees used */
2508     proto_register_field_array(proto_bssap, hf, array_length(hf));
2509     proto_register_subtree_array(ett, array_length(ett));
2510
2511     bssap_module = prefs_register_protocol(proto_bssap, proto_reg_handoff_bssap);
2512
2513     prefs_register_enum_preference(bssap_module,
2514                        "bsap_or_bssap",
2515                        "Identify to sub-dissector as",
2516                        "For the sake of sub-dissectors registering to accept data "
2517                        "from the BSSAP/BSAP dissector, this defines whether it is "
2518                        "identified as BSSAP or BSAP.",
2519                        &bssap_or_bsap_global,
2520                        bssap_or_bsap_options,
2521                        ENC_BIG_ENDIAN);
2522
2523     prefs_register_enum_preference(bssap_module,
2524                        "gsm_or_lb_interface",
2525                        "Identify the BSSAP interface",
2526                        "GSM-A is the interface between the BSC and the MSC. Lb is the interface between the BSC and the SMLC.",
2527                        &gsm_or_lb_interface_global,
2528                        gsm_or_lb_interface_options,
2529                        ENC_BIG_ENDIAN);
2530
2531     prefs_register_uint_preference(bssap_module, "ssn",
2532                        "Subsystem number used for BSSAP",
2533                        "Set Subsystem number used for BSSAP/BSSAP+",
2534                        10, &global_bssap_ssn);
2535     bssap_dissector_table = register_dissector_table("bssap.pdu_type", "BSSAP Message Type", FT_UINT8, BASE_DEC);
2536     bsap_dissector_table = register_dissector_table("bsap.pdu_type", "BSAP Message Type", FT_UINT8, BASE_DEC);
2537 }
2538
2539 void
2540 proto_reg_handoff_bssap(void)
2541 {
2542     static gboolean initialized = FALSE;
2543     static dissector_handle_t bssap_plus_handle;
2544     static guint old_bssap_ssn;
2545
2546     if (!initialized) {
2547         heur_dissector_add("sccp", dissect_bssap_heur, proto_bssap);
2548         heur_dissector_add("sua", dissect_bssap_heur, proto_bssap);
2549         /* BSSAP+ */
2550         bssap_plus_handle = create_dissector_handle(dissect_bssap_plus, proto_bssap);
2551
2552         data_handle = find_dissector("data");
2553         rrlp_handle = find_dissector("rrlp");
2554         initialized = TRUE;
2555     } else {
2556         dissector_delete_uint("sccp.ssn", old_bssap_ssn, bssap_plus_handle);
2557     }
2558
2559     dissector_add_uint("sccp.ssn", global_bssap_ssn, bssap_plus_handle);
2560     old_bssap_ssn = global_bssap_ssn;
2561 }