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