Don't guard col_append_str with check_col
[metze/wireshark/wip.git] / epan / dissectors / packet-gsm_bssmap_le.c
1 /* packet-gsm_bssmap_le.c
2  * Routines for GSM Lb Interface BSSMAP dissection
3  *
4  * Copyright 2008, Johnny Mitrevski <mitrevj@hotmail.com>
5  *
6  * 3GPP TS 49.031 version v7.4.0 (2009-09)
7  *
8  * $Id$
9  *
10  * Wireshark - Network traffic analyzer
11  * By Gerald Combs <gerald@wireshark.org>
12  * Copyright 1998 Gerald Combs
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <stdio.h>
34 #include <stdlib.h>
35
36 #include <string.h>
37
38 #include <epan/packet.h>
39 #include <epan/tap.h>
40 #include <epan/emem.h>
41
42 #include "packet-bssap.h"
43 #include "packet-sccp.h"
44 #include "packet-gsm_a_common.h"
45 #include "packet-e212.h"
46
47 /* PROTOTYPES/FORWARDS */
48
49 /* Message Type definitions */
50 #define BSSMAP_LE_PERFORM_LOCATION_REQUEST              43
51 #define BSSMAP_LE_PERFORM_LOCATION_RESPONSE             45
52 #define BSSMAP_LE_PERFORM_LOCATION_ABORT                46
53 #define BSSMAP_LE_PERFORM_LOCATION_INFORMATION          47
54 #define BSSMAP_LE_CONNECTION_ORIENTED_INFORMATION       42
55 #define BSSMAP_LE_CONNECTIONLESS_INFORMATION            58
56 #define BSSMAP_LE_RESET                                 48
57 #define BSSMAP_LE_RESET_ACKNOWLEDGE                     49
58
59 const value_string gsm_bssmap_le_msg_strings[] = {
60         { 0, "Reserved" },
61         { 1, "Reserved" },
62         { 2, "Reserved" },
63         { 3, "Reserved" },
64         { 4, "Reserved" },
65         { BSSMAP_LE_PERFORM_LOCATION_REQUEST, "Perform Location Request" },
66         { BSSMAP_LE_PERFORM_LOCATION_RESPONSE, "Perform Location Response" },
67         { BSSMAP_LE_PERFORM_LOCATION_ABORT, "Perform Location Abort" },
68         { BSSMAP_LE_PERFORM_LOCATION_INFORMATION, "Perform Location Information" },
69         { BSSMAP_LE_CONNECTION_ORIENTED_INFORMATION, "Connection Oriented Information" },
70         { BSSMAP_LE_CONNECTIONLESS_INFORMATION, "Connectionless Information" },
71         { BSSMAP_LE_RESET, "Reset" },
72         { BSSMAP_LE_RESET_ACKNOWLEDGE, "Reset Acknowledge" },
73         { 0, NULL }    /*Null terminated list. Make sure we add this to our value/string structures. */
74 };
75
76 /* Information Element definitions */
77 #define BSSMAP_LE_LCS_QOS                                    62
78 #define BSSMAP_LE_LCS_PRIORITY                               67
79 #define BSSMAP_LE_LOCATION_TYPE                              68
80 #define BSSMAP_LE_GANSS_LOCATION_TYPE                        130
81 #define BSSMAP_LE_GEOGRAPHIC_LOCATION                        69
82 #define BSSMAP_LE_POSITIONING_DATA                           70
83 #define BSSMAP_LE_GANSS_POSITIONING_DATA                     131
84 #define BSSMAP_LE_VELOCITY_DATA                              85
85 #define BSSMAP_LE_LCS_CAUSE                                  71
86 #define BSSMAP_LE_LCS_CLIENT_TYPE                            72
87 #define BSSMAP_LE_APDU                                       73
88 #define BSSMAP_LE_NETWORK_ELEMENT_IDENTITY                   74
89 #define BSSMAP_LE_REQUESTED_GPS_ASSISTANCE_DATA              75
90 #define BSSMAP_LE_REQUESTED_GANSS_ASSISTANCE_DATA            65
91 #define BSSMAP_LE_DECIPHERING_KEYS                           76
92 #define BSSMAP_LE_RETURN_ERROR_REQUEST                       77
93 #define BSSMAP_LE_RETURN_ERROR_CAUSE                         78
94 #define BSSMAP_LE_SEGMENTATION                               79
95 #define BSSMAP_LE_CLASSMARK_INFORMATION_TYPE_3               19
96 #define BSSMAP_LE_CAUSE                                      4
97 #define BSSMAP_LE_CELL_IDENTIFIER                            5
98 #define BSSMAP_LE_CHOSEN_CHANNEL                             33
99 #define BSSMAP_LE_IMSI                                       0
100 #define BSSMAP_LE_RESERVED_NOTE1                             1
101 #define BSSMAP_LE_RESERVED_NOTE2                             2
102 #define BSSMAP_LE_RESERVED_NOTE3                             3
103 #define BSSMAP_LE_LCS_CAPABILITY                             80
104 #define BSSMAP_LE_PACKET_MEASUREMENT_REPORT                  81
105 #define BSSMAP_LE_CELL_IDENTITY_LIST                         82
106 #define BSSMAP_LE_IMEI                                       128
107
108 const value_string gsm_bssmap_le_elem_strings[] = {
109         { BSSMAP_LE_LCS_QOS, "LCS QoS" },
110         { BSSMAP_LE_LCS_PRIORITY, "LCS Priority" },
111         { BSSMAP_LE_LOCATION_TYPE, "Location Type" },
112         { BSSMAP_LE_GANSS_LOCATION_TYPE, "GANSS Location Type" },
113         { BSSMAP_LE_GEOGRAPHIC_LOCATION, "Geographic Location" },
114         { BSSMAP_LE_POSITIONING_DATA, "Positioning Data" },
115         { BSSMAP_LE_GANSS_POSITIONING_DATA, "GANSS Positioning Data" },
116         { BSSMAP_LE_VELOCITY_DATA, "Velocity Data" },
117         { BSSMAP_LE_LCS_CAUSE, "LCS Cause" },
118         { BSSMAP_LE_LCS_CLIENT_TYPE, "LCS Client Type" },
119         { BSSMAP_LE_APDU, "APDU" },
120         { BSSMAP_LE_NETWORK_ELEMENT_IDENTITY, "Network Element Identity" },
121         { BSSMAP_LE_REQUESTED_GPS_ASSISTANCE_DATA, "Requested GPS Assistance Data" },
122         { BSSMAP_LE_REQUESTED_GANSS_ASSISTANCE_DATA, "Requested GANSS Assistance Data" },
123         { BSSMAP_LE_DECIPHERING_KEYS, "Deciphering Keys" },
124         { BSSMAP_LE_RETURN_ERROR_REQUEST, "Return Error Request" },
125         { BSSMAP_LE_RETURN_ERROR_CAUSE, "Return Error Cause" },
126         { BSSMAP_LE_SEGMENTATION, "Segmentation" },
127         { BSSMAP_LE_CLASSMARK_INFORMATION_TYPE_3, "Classmark Information Type 3" },
128         { BSSMAP_LE_CAUSE, "Cause" },
129         { BSSMAP_LE_CELL_IDENTIFIER, "Cell Identifier" },
130         { BSSMAP_LE_CHOSEN_CHANNEL, "Chosen Channel" },
131         { BSSMAP_LE_IMSI, "IMSI" },
132         { BSSMAP_LE_RESERVED_NOTE1, "Reserved" },
133         { BSSMAP_LE_RESERVED_NOTE2, "Reserved" },
134         { BSSMAP_LE_RESERVED_NOTE3, "Reserved" },
135         { BSSMAP_LE_LCS_CAPABILITY, "LCS Capability" },
136         { BSSMAP_LE_PACKET_MEASUREMENT_REPORT, "Packet Measurement Report" },
137         { BSSMAP_LE_CELL_IDENTITY_LIST, "Cell Identity List" },
138         { BSSMAP_LE_IMEI, "IMEI" },
139         { 0, NULL }
140 };
141
142 static const value_string gsm_apdu_protocol_id_strings[] = {
143         { 0,    "reserved" },
144         { 1,    "BSSLAP" },
145         { 2,    "LLP" },
146         { 3,    "SMLCPP" },
147         { 0, NULL },
148 };
149
150 /* Velocity Requested definitions */
151 static const value_string bssmap_le_velocity_requested_vals[] = {
152         { 0, "do not report velocity" },
153         { 1, "report velocity if available" },
154         { 0, NULL}
155 };
156
157 /* Vertical Coordinate definitions */
158 static const value_string bssmap_le_vertical_coordinate_indicator_vals[] = {
159         { 0, "vertical coordinate not requested" },
160         { 1, "vertical coordinate is requested" },
161         { 0, NULL}
162 };
163
164 /* Horizontal Accuracy definitions */
165 static const value_string bssmap_le_horizontal_accuracy_indicator_vals[] = {
166         { 0, "horizontal accuracy is not specified" },
167         { 1, "horizontal accuracy is specified" },
168         { 0, NULL}
169 };
170
171 /* Vertical Accuracy definitions */
172 static const value_string bssmap_le_vertical_accuracy_indicator_vals[] = {
173         { 0, "vertical accuracy is not specified" },
174         { 1, "vertical accuracy is specified" },
175         { 0, NULL}
176 };
177
178 /* Response Time definitions */
179 static const value_string bssmap_le_response_time_definitions_vals[] = {
180         { 0, "Response Time is not specified" },
181         { 1, "Low Delay" },
182         { 2, "Delay Tolerant" },
183         { 3, "reserved" },
184         { 0, NULL}
185 };
186
187 /* Initialize the protocol and registered fields */
188 static int proto_bssmap_le = -1;
189 int hf_gsm_bssmap_le_elem_id = -1;
190
191 /* The following hf_* variables are used to hold the Wireshark IDs of
192 * our header fields; they are filled out when we call
193 * proto_register_field_array() in proto_register_bssmap_le()
194 */
195 static int hf_gsm_bssmap_le_msg_type = -1;
196 static int hf_gsm_bssmap_le_apdu_protocol_id = -1;
197 static int hf_gsm_bssmap_le_spare = -1;
198 static int hf_gsm_bssmap_le_ciphering_key_flag = -1;
199 static int hf_gsm_bssmap_le_current_deciphering_key_value = -1;
200 static int hf_gsm_bssmap_le_next_deciphering_key_value = -1;
201 static int hf_gsm_bssmap_le_lcs_cause_value =-1;
202 static int hf_gsm_bssmap_le_diagnostic_value = -1;
203 static int hf_gsm_bssmap_le_client_category = -1;
204 static int hf_gsm_bssmap_le_client_subtype = -1;
205 static int hf_gsm_bssmap_le_velocity_requested = -1;
206 static int hf_gsm_bssmap_le_vertical_coordinate_indicator = -1;
207 static int hf_gsm_bssmap_le_horizontal_accuracy_indicator = -1;
208 static int hf_gsm_bssmap_le_horizontal_accuracy = -1;
209 static int hf_gsm_bssmap_le_vertical_accuracy_indicator = -1;
210 static int hf_gsm_bssmap_le_vertical_accuracy = -1;
211 static int hf_gsm_bssmap_le_response_time_category = -1;
212
213 /* Initialize the subtree pointers */
214 static gint ett_bssmap_le_msg = -1;
215
216 static dissector_handle_t gsm_bsslap_handle = NULL;
217
218 static packet_info *g_pinfo;
219 static proto_tree *g_tree;
220
221 #define NUM_GSM_BSSMAP_LE_ELEM (sizeof(gsm_bssmap_le_elem_strings)/sizeof(value_string))
222 gint ett_gsm_bssmap_le_elem[NUM_GSM_BSSMAP_LE_ELEM];
223
224 /*
225  * 10.3 APDU
226  */
227
228 static guint16
229 de_bmaple_apdu(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
230 {
231         guint32 curr_offset;
232         guint8  apdu_protocol_id;
233         tvbuff_t *APDU_tvb;
234
235         curr_offset = offset;
236
237         /* curr_offset + 1 is a hack, the length part here is 2 octets and we are off by one */
238         proto_tree_add_text(tree, tvb, curr_offset+1, len, "APDU");
239
240         /*
241          * dissect the embedded APDU message
242          * if someone writes a TS 09.31 dissector
243          *
244          * The APDU octets 4 to n are coded in the same way as the
245          * equivalent octet in the APDU element of 3GPP TS 49.031 BSSAP-LE.
246          */
247
248         apdu_protocol_id = tvb_get_guint8(tvb,curr_offset+1);
249         proto_tree_add_item(tree, hf_gsm_bssmap_le_apdu_protocol_id, tvb, curr_offset+1, 1, FALSE);
250
251         switch(apdu_protocol_id){
252         case 1:
253                 /* BSSLAP
254                  * the embedded message is as defined in 3GPP TS 08.71(3GPP TS 48.071 version 7.2.0 Release 7)
255                  */
256                 APDU_tvb = tvb_new_subset(tvb, curr_offset+2, len-1, len-1);
257                 if(gsm_bsslap_handle)
258                         call_dissector(gsm_bsslap_handle, APDU_tvb, g_pinfo, g_tree);
259                 break;
260         case 2:
261                 /* LLP
262                  * The embedded message contains a Facility Information Element as defined in 3GPP TS 04.71
263                  * excluding the Facility IEI and length of Facility IEI octets defined in 3GPP TS 04.71.(3GPP TS 44.071).
264                  */
265                 break;
266         case 3:
267                 /* SMLCPP
268                  * The embedded message is as defined in 3GPP TS 08.31(TS 48.031).
269                  */
270                 break;
271         default:
272                 break;
273         }
274
275         curr_offset += len;
276
277         EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
278
279         return(curr_offset - offset);
280 }
281 /*
282  * 10.4 Cause
283  * coded as the value part of the Cause IE defined in 3GPP TS 48.008
284  */
285 /*
286  * 10.5 Cell Identifier
287  * coded as the value part of the Cell Identifier IE defined in 3GPP TS 48.008
288  */
289 /*
290  * 10.6 Chosen Channel
291  * coded as the value part of the Chosen Channel IE defined in 3GPP TS 48.008
292  */
293 /*
294  * 10.7 Classmark Information Type 3
295  * coded as the value part of the Classmark Information Type 3 IE defined in 3GPP TS 48.008
296  */
297 /*
298  * 10.8 Deciphering Keys
299  */
300 static guint16
301 de_bmaple_decihp_keys(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
302 {
303         gint bit_offset;
304
305         /* Spare bits */
306         bit_offset = (offset<<3);
307         proto_tree_add_bits_item(tree, hf_gsm_bssmap_le_spare, tvb, bit_offset, 7, FALSE);
308         bit_offset += 7;
309
310         /* Extract the Ciphering Key Flag and add to protocol tree */
311         proto_tree_add_bits_item(tree, hf_gsm_bssmap_le_ciphering_key_flag, tvb, bit_offset, 1, FALSE);
312         bit_offset++;
313         offset++;
314
315         /* Extract the Current Deciphering Key Value and add to protocol tree */
316         proto_tree_add_bits_item(tree, hf_gsm_bssmap_le_current_deciphering_key_value, tvb, bit_offset, 56, FALSE);
317         bit_offset += 56;
318         offset += 7;
319
320         /* Extract the Next Deciphering Key Value and add to protocol tree */
321         proto_tree_add_bits_item(tree, hf_gsm_bssmap_le_next_deciphering_key_value, tvb, bit_offset, 56, FALSE);
322         offset += 7;
323
324         return(len);
325 }
326 /*
327  * 10.9 Geographic Location
328  * contains an octet sequence identical to that for Geographical Information 
329  * defined in 3GPP TS 23.032..
330  */
331 /*
332  * 10.10 Requested GPS Assistance Data
333  */
334 /*
335  * 10.11 IMSI
336  * coded as the value part of the Mobile Identity IE defined in 3GPP TS 24.008 (NOTE 1)
337  * NOTE 1: The Type of identity field in the Mobile Identity IE shall
338  * be ignored by the receiver
339  */
340 /*
341  * 10.12 (void)
342  */
343 /*
344  * 10.13 LCS Cause
345  */
346 static const value_string bssmap_le_lcs_cause_values[] = {
347         { 0, "Unspecified" },
348         { 1, "System Failure" },
349         { 2, "Protocol Error" },
350         { 3, "Data missing in position request" },
351         { 4, "Unexpected data value in position request" },
352         { 5, "Position method failure" },
353         { 6, "Target MS Unreachable" },
354         { 7, "Location request aborted" },
355         { 8, "Facility not supported" },
356         { 9, "Inter-BSC Handover Ongoing" },
357         { 10, "Intra-BSC Handover Complete" },
358         { 11, "Congestion" },
359         { 12, "Inter NSE cell change" },
360         { 13, "Routing Area Update" },
361         { 14, "PTMSI reallocation" },
362         { 15, "Suspension of GPRS services" },
363         { 0, NULL}
364 };
365
366 static const value_string bssmap_le_position_method_failure_diagnostic_vals[] = {
367         { 0, "Congestion" },
368         { 1, "insufficientResources" },
369         { 2, "insufficientMeasurementData" },
370         { 3, "inconsistentMeasurementData" },
371         { 4, "locationProcedureNotCompleted" },
372         { 5, "locationProcedureNotSupportedByTargetMS" },
373         { 6, "qoSNotAttainable" },
374         { 7, "positionMethodNotAvailableInNetwork" },
375         { 8, "positionMethodNotAvailableInLocaitonArea" },
376         { 0, NULL}
377 };
378 static guint16
379 de_bmaple_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
380 {
381         guint32 curr_offset;
382
383         curr_offset = offset;
384
385         /* cause value  */
386         proto_tree_add_item(tree, hf_gsm_bssmap_le_lcs_cause_value, tvb, curr_offset, 1, FALSE);
387         curr_offset++;
388
389         if (len == 2)
390         {
391                 /* Diagnostic value (note) */
392                 proto_tree_add_item(tree, hf_gsm_bssmap_le_diagnostic_value, tvb, curr_offset, 1, FALSE);
393                 curr_offset++;
394         }
395
396         return(curr_offset - offset);
397 }
398 /*
399  * 10.14 LCS Client Type
400  */
401 /* Client Category definitions */
402 static const value_string bssmap_le_client_category[] = {
403         { 0, "Value Added Client" },
404         { 2, "PLMN Operator" },
405         { 3, "Emergency Services"},
406         { 4, "Lawful Intercept Services"},
407         { 0, NULL}
408 };
409
410 /* Client Subtype definitions */
411 static const value_string bssmap_le_client_subtype[] = {
412         { 0, "unspecified" },
413         { 1, "broadcast service" },
414         { 2, "O&M" },
415         { 3, "anonymous statistics" },
416         { 4, "Target MS service support" },
417         { 0, NULL}
418 };
419
420 static guint16
421 de_bmaple_client(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
422 {
423         guint32 curr_offset;
424         guint8 bitCount;
425
426         bitCount = offset<<3;
427         curr_offset = offset;
428
429         /* Extract the client category and add to protocol tree */
430         proto_tree_add_bits_item(tree, hf_gsm_bssmap_le_client_category, tvb, bitCount, 4, FALSE);
431         bitCount = bitCount + 4;
432
433         /* Extract the client subtype and add to protocol tree */
434         proto_tree_add_bits_item(tree, hf_gsm_bssmap_le_client_subtype, tvb, bitCount, 4, FALSE);
435         bitCount = bitCount + 4;
436         curr_offset++;
437
438         return(curr_offset - offset);
439 }
440 /*
441  * 10.15 LCS Priority
442  * coded as the LCS-Priority octet in 3GPP TS 29.002
443  */
444 /*
445  * 10.16 LCS QoS
446  */
447 static guint16
448 de_bmaple_lcs_qos(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
449 {
450         guint64 verticalCoordIndicator, velocityRequested, horizontalAccuracyIndicator, verticalAccuracyIndicator;
451         guint16 bitCount;
452
453         bitCount = offset << 3;
454
455         proto_tree_add_bits_item(tree, hf_gsm_bssmap_le_spare, tvb, bitCount, 6, FALSE);
456         bitCount = bitCount + 6;
457
458         /* Extract Velocity requested element */
459         proto_tree_add_bits_ret_val(tree, hf_gsm_bssmap_le_velocity_requested, tvb, bitCount, 1, &velocityRequested, FALSE);
460         bitCount++;
461
462         /* Extract vertical coordinator element */
463         proto_tree_add_bits_ret_val(tree, hf_gsm_bssmap_le_vertical_coordinate_indicator, tvb, bitCount, 1, &verticalCoordIndicator, FALSE);
464         bitCount++;
465
466         /* Extract horizontal accuracy element */
467         proto_tree_add_bits_ret_val(tree, hf_gsm_bssmap_le_horizontal_accuracy_indicator, tvb, bitCount, 1, &horizontalAccuracyIndicator, FALSE);
468         bitCount++;
469
470         if(horizontalAccuracyIndicator == 1)
471         {
472                 proto_tree_add_bits_item(tree, hf_gsm_bssmap_le_horizontal_accuracy, tvb, bitCount, 7, FALSE);
473                 bitCount = bitCount + 7;
474         }
475         else
476         {
477                 proto_tree_add_bits_item(tree, hf_gsm_bssmap_le_spare, tvb, bitCount, 7, FALSE);
478                 bitCount = bitCount + 7;
479         }
480
481         /* Extract vertical accuracy element */
482         proto_tree_add_bits_ret_val(tree, hf_gsm_bssmap_le_vertical_accuracy_indicator, tvb, bitCount, 1, &verticalAccuracyIndicator, FALSE);
483         bitCount++;
484
485         if(verticalAccuracyIndicator == 1)
486         {
487                 proto_tree_add_bits_item(tree, hf_gsm_bssmap_le_vertical_accuracy, tvb, bitCount, 7, FALSE);
488                 bitCount = bitCount + 7;
489         }
490         else
491         {
492                 proto_tree_add_bits_item(tree, hf_gsm_bssmap_le_spare, tvb, bitCount, 7, FALSE);
493                 bitCount = bitCount + 7;
494         }
495
496         proto_tree_add_bits_item(tree, hf_gsm_bssmap_le_response_time_category, tvb, bitCount, 2, FALSE);
497         bitCount = bitCount + 2;
498
499         return(len);
500 }
501 /*
502  * 10.17 (void)
503  */
504 /*
505  * 10.18 Location Type
506  */
507 /*
508  * 10.19 Network Element Identity
509  */
510 /*
511  * 10.20 Positioning Data
512  */
513 static guint16
514 de_bmaple_pos_dta(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
515 {
516         tvbuff_t *data_tvb;
517         guint32 curr_offset;
518
519         curr_offset = offset;
520
521         data_tvb = tvb_new_subset(tvb, curr_offset, len, len);
522         dissect_geographical_description(data_tvb, g_pinfo, tree);
523
524         return(len);
525 }
526 /*
527  * 10.21 Return Error Request
528  */
529 /*
530  * 10.22 Return Error Cause
531  */
532 /*
533  * 10.23 (void)
534  */
535 /*
536  * 10.24 Segmentation
537  */
538 /*
539  * 10.25 (void)
540  */
541 /*
542  * 10.26 LCS Capability
543  * coded as the value part of the LCS Capability
544  * information element in 3GPP TS 48.018, not including
545  * 3GPP TS 48.018 IEI and length indicator
546  */
547 /* Dissector for the LCS Capability element */
548 static guint16
549 be_lcs_capability(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
550 {
551         /* Extract the LCS Capability element and add to protocol tree */
552         proto_tree_add_text(tree, tvb, offset, len, "Not decoded yet");
553         return len;
554 }
555
556 /*
557  * 10.27 Packet Measurement Report
558  * coded as the Packet Measurement Report
559  * message or the Packet Enhanced Measurement Report message
560  * starting with the 6-bit MESSAGE_TYPE (see clause 11 in
561  * 3GPP TS 44.060) and ending with the Non-distribution contents
562  * (i.e. the RLC/MAC padding bits are not included). The end of the
563  * message is padded with 0-bits to the nearest octet boundary.
564  */
565 /* Dissector for the Packet Measurement Report element */
566 static guint16
567 be_packet_meas_rep(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
568 {
569         /* Extract the Packet Measurement Report element and add to protocol tree */
570         proto_tree_add_text(tree, tvb, offset, len, "Not decoded yet");
571
572         return len;
573 }
574
575 /*
576  * 10.28 Cell Identity List
577  * coded as the value part of the Cell Identity List IE 
578  * defined in 3GPP TS 48.071.
579  */
580 /* Dissector for the Measured Cell Identity List element */
581 static guint16
582 be_measured_cell_identity(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
583 {
584         /* Extract the Measured Cell Identity List element and add to protocol tree */
585         proto_tree_add_text(tree, tvb, offset, len, "Not decoded yet");
586
587         return len;
588 }
589
590 /*
591  * 10.29 IMEI
592  * IMEI coded as the value part of the Mobile Identity IE defined in
593  * 3GPP TS 24.008 (NOTE 1)
594  * NOTE 1: The Type of identity field in the Mobile Identity IE shall
595  * be ignored by the receiver.
596  */
597 /*
598  * 10.30 Velocity Data
599  * contains an octet sequence identical to that for Description of 
600  * Velocity defined in 3GPP TS 23.032.
601  */
602 /*
603  * 10.31 Requested GANSS Assistance Data
604  */
605 /*
606  * 10.32 GANSS Positioning Data
607  */
608 /*
609  * 10.33 GANSS Location Type
610  */
611
612
613 #define NUM_GSM_BSSMAP_LE_MSG (sizeof(gsm_bssmap_le_msg_strings)/sizeof(value_string))
614 static gint ett_gsm_bssmap_le_msg[NUM_GSM_BSSMAP_LE_MSG];
615
616 /*
617 This enum is defined in packet-gsm_a_common.h to
618 make it possible to use element dissecton from this dissector
619 in other dissectors.
620
621 It is shown here as a comment for easier reference.
622
623 Note this enum must be of the same size as the element decoding list below
624
625 typedef enum
626 {
627         DE_BMAPLE_LCSQOS,                       / 10.16 LCS QoS /
628         DE_BMAPLE_LCS_PRIO,                     / LCS Priority /
629         DE_BMAPLE_LOC_TYPE,                     / 10.18 Location Type /
630         DE_BMAPLE_GANSS_LOC_TYPE,       / GANSS Location Type / 
631         DE_BMAPLE_GEO_LOC,                      / 10.9 Geographic Location /    
632         DE_BMAPLE_POS_DATA,                     / 10.20 Positioning Data /                      
633         DE_BMAPLE_GANSS_POS_DATA,       / GANSS Positioning Data /
634         DE_BMAPLE_VELOC_DATA,           / Velocity Data /
635         DE_BMAPLE_LCS_CAUSE,            / 10.13 LCS Cause /     
636         DE_BMAPLE_LCS_CLIENT_TYPE,      / LCS Client Type /
637         DE_BMAPLE_APDU,                         / 10.3 APDU /           
638         DE_BMAPLE_NETWORK_ELEM_ID,      / Network Element Identity /
639         DE_BMAPLE_REQ_GPS_ASSIST_D, / 10.10 Requested GPS Assistance Data /     
640         DE_BMAPLE_REQ_GNSS_ASSIST_D,/ Requested GANSS Assistance Data /
641         DE_BMAPLE_DECIPH_KEYS,          / 10.8 Deciphering Keys /
642         DE_BMAPLE_RETURN_ERROR_REQ,     / Return Error Request /
643         DE_BMAPLE_RETURN_ERROR_CAUSE,   / Return Error Cause /
644         DE_BMAPLE_SEGMENTATION,         / Segmentation /
645         DE_BMAPLE_CLASSMARK_TYPE_3,     / 10.7 Classmark Information Type 3 /
646         DE_BMAPLE_CAUSE,                        / 10.4 Cause /
647         DE_BMAPLE_CELL_IDENTIFIER,      / 10.5 Cell Identifier /
648         DE_BMAPLE_CHOSEN_CHANNEL,       / 10.6 Chosen Channel /
649         DE_BMAPLE_IMSI,                         / 10.11 IMSI /
650         DE_BMAPLE_RES1,                         / Reserved /
651         DE_BMAPLE_RES2,                         / Reserved /
652         DE_BMAPLE_RES3,                         / Reserved /
653         DE_BMAPLE_LCS_CAPABILITY,       / LCS Capability /
654         DE_BMAPLE_PACKET_MEAS_REP,      / Packet Measurement Report /
655         DE_BMAPLE_MEAS_CELL_ID,         / Measured Cell Identity /
656         DE_BMAPLE_IMEI,                         / IMEI /
657         BMAPLE_NONE                                     / NONE /
658 }
659 bssmap_le_elem_idx_t;
660 */
661
662
663 guint16 (*bssmap_le_elem_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len) = {
664         /* NOTE: The null types below are defined elsewhere. i.e in packet-gsm_a_bssmap.c */
665         de_bmaple_lcs_qos,              /* 10.16 LCS QoS */
666         NULL,                                   /* LCS Priority */
667         NULL,                                   /* 10.18 Location Type */
668         be_ganss_loc_type,              /* GANSS Location Type */
669         NULL,                                   /* 10.9 Geographic Location */
670         de_bmaple_pos_dta,              /* 10.20 Positioning Data */
671         be_ganss_pos_dta,   /* GANSS Positioning Data */
672         NULL,   /* Velocity Data */
673         de_bmaple_cause,   /* 10.13 LCS Cause */
674         de_bmaple_client,   /* LCS Client Type */
675         de_bmaple_apdu, /* APDU */
676         NULL,   /* Network Element Identity */
677         NULL,   /* Requested GPS Assitance Data */
678         be_ganss_ass_dta,   /* Requested GANSS Assistance Data */
679         de_bmaple_decihp_keys,   /* 10.8 Deciphering Keys */
680         NULL,   /* Return Error Request */
681         NULL,   /* Return Error Cause */
682         NULL,   /* Segmentation */
683         NULL,   /* 10.7 Classmark Information Type 3 */
684         NULL,   /* Cause */
685         NULL,   /* Cell Identifier */
686         NULL,   /* 10.6 Chosen Channel */
687         de_mid,   /* 10.11 IMSI */
688         NULL,   /* Reserved */
689         NULL,   /* Reserved */
690         NULL,   /* Reserved */
691         be_lcs_capability, /* LCS Capability */
692         be_packet_meas_rep, /* Packet Measurement Report */
693         be_measured_cell_identity, /* Measured Cell Identity List */
694         de_mid,    /* IMEI (use same dissector as IMSI) */
695
696         NULL,   /* NONE */
697         
698 };
699
700 /*
701  * 9.1 PERFORM LOCATION REQUEST
702  */
703 static void
704 bssmap_le_perf_loc_request(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
705 {
706         guint32 curr_offset;
707         guint32 consumed;
708         guint   curr_len;
709
710         curr_offset = offset;
711         curr_len = len;
712
713         /* Location Type 9.1.1 M 3-n */
714         ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_LOC_TYPE].value, GSM_A_PDU_TYPE_BSSMAP, BE_LOC_TYPE, NULL)
715         /* Cell Identifier 9.1.2 O 5-10 */
716         ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, GSM_A_PDU_TYPE_BSSMAP, BE_CELL_ID, NULL);
717         /* Classmark Information Type 3 9.1.3 O 3-14 */
718         ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_CM_INFO_3].value, GSM_A_PDU_TYPE_BSSMAP, BE_CM_INFO_3, NULL);
719         /* LCS Client Type 9.1.4 C (note 3) 3-n */
720         ELEM_OPT_TLV(gsm_bssmap_le_elem_strings[DE_BMAPLE_LCS_CLIENT_TYPE].value, GSM_PDU_TYPE_BSSMAP_LE, DE_BMAPLE_LCS_CLIENT_TYPE, NULL);
721         /* Chosen Channel 9.1.5 O 2 */
722         ELEM_OPT_TV(gsm_bssmap_elem_strings[BE_CHOSEN_CHAN].value, GSM_A_PDU_TYPE_BSSMAP, BE_CHOSEN_CHAN, NULL);
723         /* LCS Priority 9.1.6 O 3-n */
724         ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_LCS_PRIO].value, GSM_A_PDU_TYPE_BSSMAP, BE_LCS_PRIO, NULL);
725         /* LCS QoS 9.1.6a C (note 1) 3-n */
726         ELEM_OPT_TLV(gsm_bssmap_le_elem_strings[DE_BMAPLE_LCSQOS].value, GSM_PDU_TYPE_BSSMAP_LE, DE_BMAPLE_LCSQOS, NULL);
727         /* GPS Assistance Data 9.1.7 C (note 2) 3-n */
728         ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_GPS_ASSIST_DATA].value, GSM_A_PDU_TYPE_BSSMAP, BE_GPS_ASSIST_DATA, NULL);
729         /* APDU 9.1.8 O 3-n */
730         ELEM_OPT_TLV(gsm_bssmap_le_elem_strings[DE_BMAPLE_APDU].value, GSM_PDU_TYPE_BSSMAP_LE, DE_BMAPLE_APDU, NULL);
731         /* LCS Capability 9.1.9 O */
732         ELEM_OPT_TLV(gsm_bssmap_le_elem_strings[DE_BMAPLE_LCS_CAPABILITY].value, GSM_PDU_TYPE_BSSMAP_LE, DE_BMAPLE_LCS_CAPABILITY, NULL);
733         /* Packet Measurement Report 9.1.10 O*/
734         ELEM_OPT_TLV(gsm_bssmap_le_elem_strings[DE_BMAPLE_PACKET_MEAS_REP].value, GSM_PDU_TYPE_BSSMAP_LE, DE_BMAPLE_PACKET_MEAS_REP, NULL);
735         /* Measured Cell Identity List 9.1.11 O*/
736         ELEM_OPT_TLV(gsm_bssmap_le_elem_strings[DE_BMAPLE_MEAS_CELL_ID].value, GSM_PDU_TYPE_BSSMAP_LE, DE_BMAPLE_MEAS_CELL_ID, NULL);
737         /* IMSI 9.1.12  O (note 4)      5-10 */
738         ELEM_OPT_TLV(gsm_bssmap_le_elem_strings[DE_BMAPLE_IMSI].value, GSM_PDU_TYPE_BSSMAP_LE, DE_BMAPLE_IMSI, NULL);
739         /* IMEI 9.1.13  O (note 4)      10 (use same decode as IMSI) */
740         ELEM_OPT_TLV(gsm_bssmap_le_elem_strings[DE_BMAPLE_IMEI].value, GSM_PDU_TYPE_BSSMAP_LE, DE_BMAPLE_IMEI, NULL);
741         /* GANSS Location Type  9.1.14  C       3 */
742         ELEM_OPT_TLV(gsm_bssmap_le_elem_strings[DE_BMAPLE_GANSS_LOC_TYPE].value, GSM_PDU_TYPE_BSSMAP_LE, DE_BMAPLE_GANSS_LOC_TYPE, NULL);
743         /* GANSS Assistance Data        9.1.15  C (note 5)      3-n */
744         ELEM_OPT_TLV(gsm_bssmap_le_elem_strings[DE_BMAPLE_REQ_GNSS_ASSIST_D].value, GSM_PDU_TYPE_BSSMAP_LE, DE_BMAPLE_REQ_GNSS_ASSIST_D, NULL);
745
746         EXTRANEOUS_DATA_CHECK(curr_len, 0);
747
748 }
749
750 /*
751  * 9.2 PERFORM LOCATION RESPONSE
752  */
753 static void
754 bssmap_le_perf_loc_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
755 {
756         guint32 curr_offset;
757         guint32 consumed;
758         guint   curr_len;
759
760         curr_offset = offset;
761         curr_len = len;
762
763         /* Location Estimate 9.2.1 C (note 1) 3-n */
764         ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_LOC_EST].value, BSSAP_PDU_TYPE_BSSMAP, BE_LOC_EST, NULL);
765         /* Positioning Data 9.2.2 O 3-n */
766         ELEM_OPT_TLV(gsm_bssmap_le_elem_strings[DE_BMAPLE_POS_DATA].value, GSM_PDU_TYPE_BSSMAP_LE, DE_BMAPLE_POS_DATA, NULL);
767         /* Deciphering Keys 9.2.3 C (note 2) 3-n */
768         ELEM_OPT_TLV(gsm_bssmap_le_elem_strings[DE_BMAPLE_DECIPH_KEYS].value, GSM_PDU_TYPE_BSSMAP_LE, DE_BMAPLE_DECIPH_KEYS, NULL);
769         /* LCS Cause 9.2.4 C (note 3) 3-n */
770         ELEM_OPT_TLV(gsm_bssmap_le_elem_strings[DE_BMAPLE_LCS_CAUSE].value, GSM_PDU_TYPE_BSSMAP_LE, DE_BMAPLE_LCS_CAUSE, NULL);
771         /* Velocity Estimate    9.2.5   O       3-n */
772         ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_VEL_EST].value, BSSAP_PDU_TYPE_BSSMAP, BE_VEL_EST, NULL);
773         /* GANSS Positioning Data       9.2.6   O       3-n */
774         ELEM_OPT_TLV(gsm_bssmap_le_elem_strings[DE_BMAPLE_GANSS_POS_DATA].value, GSM_PDU_TYPE_BSSMAP_LE, DE_BMAPLE_GANSS_POS_DATA, NULL);
775
776         EXTRANEOUS_DATA_CHECK(curr_len, 0);
777 }
778
779 /*
780  * 9.8 CONNECTION ORIENTED INFORMATION
781  */
782 static void
783 bssmap_le_connection_oriented(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
784 {
785         guint32 curr_offset;
786         guint32 consumed;
787         guint   curr_len;
788
789         curr_offset = offset;
790         curr_len = len;
791
792         /* APDU 9.8.1 M 3-n */
793         ELEM_MAND_TLV(gsm_bssmap_le_elem_strings[DE_BMAPLE_APDU].value, GSM_PDU_TYPE_BSSMAP_LE, DE_BMAPLE_APDU, NULL);
794         /* Segmentation 9.8.2 */
795         ELEM_OPT_TLV(gsm_bssmap_elem_strings[BE_SEG].value, BSSAP_PDU_TYPE_BSSMAP, BE_SEG, NULL);
796
797         EXTRANEOUS_DATA_CHECK(curr_len, 0);
798 }
799
800 /*
801  * 9.9  CONNECTIONLESS INFORMATION
802  *
803 Network Element Identity (source)       3.2.2.69        Both    M       3-n
804 Network Element Identity (target)       3.2.2.69        Both    M       3-n
805 APDU    3.2.2.68        Both    M       3-n 
806 Segmentation    3.2,2,74        Both    C (note 1)      5
807 Return Error Request    3.2.2.72        Both    C (note 2)      3-n
808 Return Error Cause      3.2.2.73        Both    C (note 3)      3-n 
809 */
810
811 /*
812  * 9.11 RESET ACKNOWLEDGE
813  * no data
814  */
815
816 /*
817  * 9.12 PERFORM LOCATION INFORMATION
818  */
819 static void
820 bssmap_le_perf_loc_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
821 {
822         guint32 curr_offset;
823         guint32 consumed;
824         guint   curr_len;
825
826         curr_offset = offset;
827         curr_len = len;
828
829         /* Cell Identifier 9.12.1 M */
830         ELEM_MAND_TLV(gsm_bssmap_elem_strings[BE_CELL_ID].value, GSM_A_PDU_TYPE_BSSMAP, BE_CELL_ID, NULL);
831         /* APDU 9.1.8 O 3-n */
832         ELEM_OPT_TLV(gsm_bssmap_le_elem_strings[DE_BMAPLE_APDU].value, GSM_PDU_TYPE_BSSMAP_LE, DE_BMAPLE_APDU, NULL);
833
834         EXTRANEOUS_DATA_CHECK(curr_len, 0);
835 }
836
837 static void (*bssmap_le_msg_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
838         NULL,
839         NULL,
840         NULL,
841         NULL,
842         NULL,
843         bssmap_le_perf_loc_request,     /* Perform Location Request */
844         bssmap_le_perf_loc_resp,        /* Perform Location Response */
845         bssmap_perf_loc_abort,          /* Abort */
846         bssmap_le_perf_loc_info,        /* Perform Location Information */
847         bssmap_le_connection_oriented,  /* Connection Oriented Information */
848         NULL,                                           /* Connectionless Information */
849         bssmap_reset,                           /* Reset */
850         NULL,           /* Reset Acknowledge */
851
852         NULL,   /* NONE */
853 };
854
855 void
856 dissect_bssmap_le(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
857 {
858         static gsm_a_tap_rec_t  tap_rec[4];
859         static gsm_a_tap_rec_t  *tap_p;
860         static guint                    tap_current=0;
861         guint8  oct;
862         guint32 offset, saved_offset;
863         guint32 len;
864         gint    idx;
865         proto_item      *bssmap_le_item = NULL;
866         proto_tree      *bssmap_le_tree = NULL;
867         const gchar     *str;
868         sccp_msg_info_t* sccp_msg;
869
870         sccp_msg = pinfo->sccp_info;
871
872         if (!(sccp_msg && sccp_msg->data.co.assoc)) {
873                 sccp_msg = NULL;
874         }
875
876         col_append_str(pinfo->cinfo, COL_INFO, "(BSSMAP LE) ");
877
878         /*
879          * set tap record pointer
880          */
881         tap_current++;
882         if (tap_current >= 4)
883         {
884                 tap_current = 0;
885         }
886         tap_p = &tap_rec[tap_current];
887
888
889         offset = 0;
890         saved_offset = offset;
891
892         g_pinfo = pinfo;
893         g_tree = tree;
894
895         len = tvb_length(tvb);
896
897         /*
898          * add BSSMAP message name
899          */
900         oct = tvb_get_guint8(tvb, offset++);
901
902         str = match_strval_idx((guint32) oct, gsm_bssmap_le_msg_strings, &idx);
903
904         if (sccp_msg && !sccp_msg->data.co.label) {
905                 sccp_msg->data.co.label = se_strdup(val_to_str((guint32) oct, gsm_bssmap_le_msg_strings, "BSSMAP LE(0x%02x)"));
906         }
907
908         /*
909          * create the protocol tree
910          */
911         if (str == NULL)
912         {
913                 bssmap_le_item =
914                 proto_tree_add_protocol_format(tree, proto_bssmap_le, tvb, 0, len,
915                         "Lb - I/F BSSMAP LE - Unknown BSSMAP Message Type (0x%02x)",
916                         oct);
917
918                 bssmap_le_tree = proto_item_add_subtree(bssmap_le_item, ett_bssmap_le_msg);
919         }
920         else
921         {
922                 bssmap_le_item =
923                 proto_tree_add_protocol_format(tree, proto_bssmap_le, tvb, 0, -1,
924                         "Lb - I/F BSSMAP LE - %s",
925                         str);
926
927                 bssmap_le_tree = proto_item_add_subtree(bssmap_le_item, ett_gsm_bssmap_le_msg[idx]);
928
929                 if (check_col(pinfo->cinfo, COL_INFO))
930                 {
931                         col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", str);
932                 }
933
934                 /*
935                  * add BSSMAP message name
936                  */
937                 proto_tree_add_uint_format(bssmap_le_tree, hf_gsm_bssmap_le_msg_type,
938                 tvb, saved_offset, 1, oct, "Message Type %s",str);
939         }
940
941         tap_p->pdu_type = BSSAP_PDU_TYPE_BSSMAP;
942         tap_p->message_type = oct;
943
944         tap_queue_packet(gsm_a_tap, pinfo, tap_p);
945
946         if (str == NULL) return;
947
948         if (offset >= len) return;
949
950         /*
951          * decode elements
952          */
953         if (bssmap_le_msg_fcn[idx] == NULL)
954         {
955                 proto_tree_add_text(bssmap_le_tree,
956                         tvb, offset, len - offset,
957                         "Message Elements");
958         }
959         else
960         {
961                 (*bssmap_le_msg_fcn[idx])(tvb, bssmap_le_tree, offset, len - offset);
962         }
963 }
964
965 /* Register the protocol with Wireshark */
966 void
967 proto_register_gsm_bssmap_le(void)
968 {
969         guint           i;
970         guint           last_offset;
971
972         /* Setup list of header fields */
973         static hf_register_info hf[] = {
974                 { &hf_gsm_bssmap_le_msg_type,
975                   { "BSSMAP LE Message Type",   "bssmap_le.msgtype",
976                     FT_UINT8, BASE_HEX, VALS(gsm_bssmap_le_msg_strings), 0x0,
977                     NULL, HFILL }
978                 },
979                 { &hf_gsm_bssmap_le_elem_id,
980                   { "Element ID",       "bssmap_le.elem_id",
981                     FT_UINT8, BASE_DEC, NULL, 0,
982                     NULL, HFILL }
983                 },
984                 { &hf_gsm_bssmap_le_apdu_protocol_id,
985                   { "Protocol ID", "bssmap_le.apdu_protocol_id",
986                     FT_UINT8, BASE_DEC, VALS(gsm_apdu_protocol_id_strings), 0x0,
987                     "APDU embedded protocol id", HFILL }
988                 },
989                 { &hf_gsm_bssmap_le_spare,
990                   { "Spare", "gsm_bssmap_le.spare", 
991                     FT_UINT8, BASE_HEX, NULL, 0x0,
992                     NULL, HFILL}
993                 },
994                 { &hf_gsm_bssmap_le_ciphering_key_flag,
995                   { "Ciphering Key Flag", "gsm_bssmap_le.decipheringKeys.flag", 
996                     FT_UINT8, BASE_DEC, NULL, 0x0, 
997                     NULL, HFILL}
998                 },
999                 { &hf_gsm_bssmap_le_current_deciphering_key_value,
1000                   { "Current Deciphering Key Value", "gsm_bssmap_le.decipheringKeys.current", 
1001                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, 
1002                     HFILL}
1003                 },
1004                 { &hf_gsm_bssmap_le_next_deciphering_key_value,
1005                   { "Next Deciphering Key Value", "gsm_bssmap_le.decipheringKeys.next", 
1006                     FT_UINT8, BASE_DEC, NULL, 0x0, 
1007                     NULL, HFILL}
1008                 },
1009                 { &hf_gsm_bssmap_le_lcs_cause_value,
1010                   { "Cause Value", "gsm_bssmap_le.lcsCauseValue", 
1011                     FT_UINT8, BASE_HEX, VALS(bssmap_le_lcs_cause_values), 0x0,
1012                     NULL, HFILL}
1013                 },
1014                 { &hf_gsm_bssmap_le_diagnostic_value,
1015                   { "Diagnostic Value", "gsm_bssmap_le.diagnosticValue", 
1016                     FT_UINT8, BASE_HEX, VALS(bssmap_le_position_method_failure_diagnostic_vals), 0x0,
1017                     NULL, HFILL}
1018                 },
1019                 { &hf_gsm_bssmap_le_client_category,
1020                   { "Client Category", "gsm_bssmap_le.lcsClientType.clientCategory", 
1021                     FT_UINT8, BASE_HEX, VALS(bssmap_le_client_category), 0x0,
1022                     NULL, HFILL}
1023                 },
1024                 { &hf_gsm_bssmap_le_client_subtype,
1025                   { "Client Subtype", "gsm_bssmap_le.lcsClientType.clientSubtype", 
1026                     FT_UINT8, BASE_HEX, VALS(bssmap_le_client_subtype), 0x0,
1027                     NULL, HFILL}
1028                 },
1029                 { &hf_gsm_bssmap_le_velocity_requested,
1030                   { "Velocity Requested", "gsm_bssmap_le.lcsQos.velocityRequested", 
1031                     FT_UINT8, BASE_HEX, VALS(bssmap_le_velocity_requested_vals), 0x0,
1032                     NULL, HFILL}
1033                 },
1034                 { &hf_gsm_bssmap_le_vertical_coordinate_indicator,
1035                   { "Vertical Coordinate Indicator", "gsm_bssmap_le.lcsQos.verticalCoordinateIndicator", 
1036                     FT_UINT8, BASE_HEX, VALS(bssmap_le_vertical_coordinate_indicator_vals), 0x0,
1037                     NULL, HFILL}
1038                 },
1039                 { &hf_gsm_bssmap_le_horizontal_accuracy_indicator,
1040                   { "Horizontal Accuracy Indicator", "gsm_bssmap_le.lcsQos.horizontalAccuracyIndicator", 
1041                     FT_UINT8, BASE_HEX, VALS(bssmap_le_horizontal_accuracy_indicator_vals), 0x0,
1042                     NULL, HFILL}
1043                 },
1044                 { &hf_gsm_bssmap_le_horizontal_accuracy,
1045                   { "Horizontal Accuracy", "gsm_bssmap_le.lcsQos.horizontalAccuracy", 
1046                     FT_UINT8, BASE_HEX, NULL, 0x0,
1047                     NULL, HFILL}
1048                 },
1049                 { &hf_gsm_bssmap_le_vertical_accuracy,
1050                   { "Vertical Accuracy", "gsm_bssmap_le.lcsQos.verticalAccuracy", 
1051                     FT_UINT8, BASE_HEX, NULL, 0x0,
1052                     NULL, HFILL}
1053                 },
1054                 { &hf_gsm_bssmap_le_vertical_accuracy_indicator,
1055                   { "Vertical Accuracy Indicator", "gsm_bssmap_le.lcsQos.verticalAccuracyIndicator", 
1056                     FT_UINT8, BASE_HEX, VALS(bssmap_le_vertical_accuracy_indicator_vals), 0x0,
1057                     NULL, HFILL}
1058                 },
1059                 { &hf_gsm_bssmap_le_response_time_category,
1060                   { "Response Time Category", "gsm_bssmap_le.lcsQos.responseTimeCategory",
1061                     FT_UINT8, BASE_HEX, VALS(bssmap_le_response_time_definitions_vals), 0x0,
1062                     NULL, HFILL}
1063                 },
1064
1065         };
1066         /* Setup protocol subtree array */
1067 #define NUM_INDIVIDUAL_ELEMS    1
1068         gint *ett[NUM_INDIVIDUAL_ELEMS + NUM_GSM_BSSMAP_LE_MSG +
1069                   NUM_GSM_BSSMAP_LE_ELEM];
1070
1071         ett[0] = &ett_bssmap_le_msg;
1072
1073         last_offset = NUM_INDIVIDUAL_ELEMS;
1074
1075         for (i=0; i < NUM_GSM_BSSMAP_LE_MSG; i++, last_offset++)
1076         {
1077                 ett_gsm_bssmap_le_msg[i] = -1;
1078                 ett[last_offset] = &ett_gsm_bssmap_le_msg[i];
1079         }
1080
1081         for (i=0; i < NUM_GSM_BSSMAP_LE_ELEM; i++, last_offset++)
1082         {
1083                 ett_gsm_bssmap_le_elem[i] = -1;
1084                 ett[last_offset] = &ett_gsm_bssmap_le_elem[i];
1085         }
1086
1087         /* Register the protocol name and description */
1088
1089         proto_bssmap_le =
1090                 proto_register_protocol("Lb-I/F BSSMAP LE", "GSM BSSMAP LE", "gsm_bssmap_le");
1091
1092         proto_register_field_array(proto_bssmap_le, hf, array_length(hf));
1093
1094         proto_register_subtree_array(ett, array_length(ett));
1095
1096         register_dissector("gsm_bssmap_le", dissect_bssmap_le, proto_bssmap_le);
1097 }
1098
1099 void
1100 proto_reg_handoff_gsm_bssmap_le(void)
1101 {
1102         dissector_handle_t bssmap_le_handle;
1103
1104         bssmap_le_handle = find_dissector("gsm_bssmap_le");
1105
1106         dissector_add("bssap.pdu_type",  BSSAP_PDU_TYPE_BSSMAP, bssmap_le_handle);
1107
1108         gsm_bsslap_handle = find_dissector("gsm_bsslap");
1109 }