2 * Routines for Base Station Subsystem GPRS Protocol dissection
3 * Copyright 2000, Susanne Edlund <susanne.edlund@ericsson.com>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 /* 3GPP TS 48.018 V 6.5.0 (2004-07) Release 6 */
37 #include <epan/packet.h>
40 #include "packet-bssgp.h"
41 #include "packet-e212.h"
42 #include "packet-gsm_a_common.h"
44 /* #define BSSGP_DEBUG */
45 #define BSSGP_LITTLE_ENDIAN FALSE
46 #define BSSGP_TRANSLATION_MAX_LEN 50
47 #define BSSGP_MASK_LEFT_OCTET_HALF 0xf0
48 #define BSSGP_MASK_RIGHT_OCTET_HALF 0x0f
49 #define BSSGP_MOBILE_IDENTITY_TYPE_IMSI 1
50 #define BSSGP_MOBILE_IDENTITY_TYPE_IMEI 2
51 #define BSSGP_MOBILE_IDENTITY_TYPE_IMEISV 3
52 #define BSSGP_MOBILE_IDENTITY_TYPE_TMSI_PTMSI 4
53 #define BSSGP_MOBILE_IDENTITY_TYPE_NO_IDENTITY 0
54 #define BSSGP_SEP ", "
55 #define BSSGP_NOT_DECODED "< Not decoded yet >"
56 #define BSSGP_UNKNOWN (-1)
57 static int bssgp_decode_nri = 0;
58 static guint bssgp_nri_length = 4;
60 static dissector_handle_t llc_handle;
61 static dissector_handle_t rrlp_handle;
62 static dissector_handle_t data_handle;
64 module_t *bssgp_module;
66 /* Initialize the protocol and registered fields */
67 static int hf_bssgp_iei_nacc_cause = -1;
68 static int proto_bssgp = -1;
69 static int hf_bssgp_pdu_type = -1;
70 static int hf_bssgp_ie_type = -1;
71 static int hf_bssgp_mcc = -1;
72 static int hf_bssgp_mnc = -1;
73 static int hf_bssgp_lac = -1;
74 static int hf_bssgp_rac = -1;
75 static int hf_bssgp_ci = -1;
76 static int hf_bssgp_ra_discriminator = -1;
77 static int hf_bssgp_appid = -1;
78 static int hf_bssgp_rcid = -1;
79 static int hf_bssgp_rrc_si_msg_type = -1;
80 static int hf_ran_inf_req_pdu_type_ext = -1;
81 static int hf_ran_inf_pdu_type_ext = -1;
82 static int hf_bssgp_nri = -1;
83 static int hf_bssgp_imsi = -1;
84 static int hf_bssgp_imei = -1;
85 static int hf_bssgp_imeisv = -1;
86 static int hf_bssgp_tmsi_ptmsi = -1;
87 static int hf_bssgp_bvci = -1;
88 static int hf_bssgp_nsei = -1;
89 static int hf_bssgp_tlli = -1;
91 /* Initialize the subtree pointers */
92 static gint ett_bssgp = -1;
93 static gint ett_bssgp_qos_profile = -1;
94 static gint ett_bssgp_gprs_timer = -1;
95 static gint ett_bssgp_cell_identifier = -1;
96 static gint ett_bssgp_channel_needed = -1;
97 static gint ett_bssgp_drx_parameters = -1;
98 static gint ett_bssgp_mobile_identity = -1;
99 static gint ett_bssgp_priority = -1;
100 static gint ett_bssgp_lsa_identifier_list = -1;
101 static gint ett_bssgp_lsa_information = -1;
102 static gint ett_bssgp_lsa_information_lsa_identification_and_attributes = -1;
103 static gint ett_bssgp_abqp = -1;
104 static gint ett_bssgp_lcs_qos = -1;
105 static gint ett_bssgp_lcs_client_type = -1;
106 static gint ett_bssgp_requested_gps_assistance_data = -1;
107 static gint ett_bssgp_requested_gps_assistance_data_satellite = -1;
108 static gint ett_bssgp_location_type = -1;
109 static gint ett_bssgp_positioning_data_positioning_method = -1;
110 static gint ett_bssgp_deciphering_keys = -1;
111 static gint ett_bssgp_lcs_cause = -1;
112 static gint ett_bssgp_lcs_capability = -1;
113 static gint ett_bssgp_rrlp_flags = -1;
114 static gint ett_bssgp_rim_pdu_indications = -1;
115 static gint ett_bssgp_mcc = -1;
116 static gint ett_bssgp_mnc = -1;
117 static gint ett_bssgp_routing_area = -1;
118 static gint ett_bssgp_location_area = -1;
119 static gint ett_bssgp_rai_ci = -1;
120 static gint ett_bssgp_rim_routing_information =-1;
121 static gint ett_bssgp_ran_information_request_application_container = -1;
122 static gint ett_bssgp_ran_information_request_container_unit = -1;
123 static gint ett_bssgp_ran_information_container_unit = -1;
124 static gint ett_bssgp_pfc_flow_control_parameters = -1;
125 static gint ett_bssgp_pfc_flow_control_parameters_pfc = -1;
126 static gint ett_bssgp_global_cn_id = -1;
127 static gint ett_bssgp_ms_radio_access_capability = -1;
128 static gint ett_bssgp_msrac_value_part = -1;
129 static gint ett_bssgp_msrac_additional_access_technologies = -1;
130 static gint ett_bssgp_msrac_access_capabilities = -1;
131 static gint ett_bssgp_msrac_a5_bits = -1;
132 static gint ett_bssgp_msrac_multislot_capability = -1;
133 static gint ett_bssgp_feature_bitmap = -1;
134 static gint ett_bssgp_positioning_data = -1;
135 static gint ett_bssgp_tlli = -1;
136 static gint ett_bssgp_tmsi_ptmsi = -1;
138 /* PDU type coding, v6.5.0, table 11.3.26, p 80 */
139 #define BSSGP_PDU_DL_UNITDATA 0x00
140 #define BSSGP_PDU_UL_UNITDATA 0x01
141 #define BSSGP_PDU_RA_CAPABILITY 0x02
142 #define BSSGP_PDU_PTM_UNITDATA 0x03
143 #define BSSGP_PDU_PAGING_PS 0x06
144 #define BSSGP_PDU_PAGING_CS 0x07
145 #define BSSGP_PDU_RA_CAPABILITY_UPDATE 0x08
146 #define BSSGP_PDU_RA_CAPABILITY_UPDATE_ACK 0x09
147 #define BSSGP_PDU_RADIO_STATUS 0x0a
148 #define BSSGP_PDU_SUSPEND 0x0b
149 #define BSSGP_PDU_SUSPEND_ACK 0x0c
150 #define BSSGP_PDU_SUSPEND_NACK 0x0d
151 #define BSSGP_PDU_RESUME 0x0e
152 #define BSSGP_PDU_RESUME_ACK 0x0f
153 #define BSSGP_PDU_RESUME_NACK 0x10
154 #define BSSGP_PDU_BVC_BLOCK 0x20
155 #define BSSGP_PDU_BVC_BLOCK_ACK 0x21
156 #define BSSGP_PDU_BVC_RESET 0x22
157 #define BSSGP_PDU_BVC_RESET_ACK 0x23
158 #define BSSGP_PDU_BVC_UNBLOCK 0x24
159 #define BSSGP_PDU_BVC_UNBLOCK_ACK 0x25
160 #define BSSGP_PDU_FLOW_CONTROL_BVC 0x26
161 #define BSSGP_PDU_FLOW_CONTROL_BVC_ACK 0x27
162 #define BSSGP_PDU_FLOW_CONTROL_MS 0x28
163 #define BSSGP_PDU_FLOW_CONTROL_MS_ACK 0x29
164 #define BSSGP_PDU_FLUSH_LL 0x2a
165 #define BSSGP_PDU_FLUSH_LL_ACK 0x2b
166 #define BSSGP_PDU_LLC_DISCARDED 0x2c
167 #define BSSGP_PDU_FLOW_CONTROL_PFC 0x2d
168 #define BSSGP_PDU_FLOW_CONTROL_PFC_ACK 0x2e
169 #define BSSGP_PDU_SGSN_INVOKE_TRACE 0x40
170 #define BSSGP_PDU_STATUS 0x41
171 #define BSSGP_PDU_DOWNLOAD_BSS_PFC 0x50
172 #define BSSGP_PDU_CREATE_BSS_PFC 0x51
173 #define BSSGP_PDU_CREATE_BSS_PFC_ACK 0x52
174 #define BSSGP_PDU_CREATE_BSS_PFC_NACK 0x53
175 #define BSSGP_PDU_MODIFY_BSS_PFC 0x54
176 #define BSSGP_PDU_MODIFY_BSS_PFC_ACK 0x55
177 #define BSSGP_PDU_DELETE_BSS_PFC 0x56
178 #define BSSGP_PDU_DELETE_BSS_PFC_ACK 0x57
179 #define BSSGP_PDU_DELETE_BSS_PFC_REQ 0x58
180 #define BSSGP_PDU_PERFORM_LOCATION_REQUEST 0x60
181 #define BSSGP_PDU_PERFORM_LOCATION_RESPONSE 0x61
182 #define BSSGP_PDU_PERFORM_LOCATION_ABORT 0x62
183 #define BSSGP_PDU_POSITION_COMMAND 0x63
184 #define BSSGP_PDU_POSITION_RESPONSE 0x64
185 #define BSSGP_PDU_RAN_INFORMATION 0x70
186 #define BSSGP_PDU_RAN_INFORMATION_REQUEST 0x71
187 #define BSSGP_PDU_RAN_INFORMATION_ACK 0x72
188 #define BSSGP_PDU_RAN_INFORMATION_ERROR 0x73
189 #define BSSGP_PDU_RAN_APPLICATION_ERROR 0x74
191 static const value_string tab_bssgp_pdu_types[] = {
192 { BSSGP_PDU_DL_UNITDATA, "DL-UNITDATA" },
193 { BSSGP_PDU_UL_UNITDATA, "UL-UNITDATA" },
194 { BSSGP_PDU_RA_CAPABILITY, "RA-CAPABILITY" },
195 { BSSGP_PDU_PTM_UNITDATA, "PTM-UNITDATA" },
196 { BSSGP_PDU_PAGING_PS, "PAGING-PS" },
197 { BSSGP_PDU_PAGING_CS, "PAGING-CS" },
198 { BSSGP_PDU_RA_CAPABILITY_UPDATE, "RA-CAPABILITY-UPDATE" },
199 { BSSGP_PDU_RA_CAPABILITY_UPDATE_ACK, "RA-CAPABILITY-UPDATE-ACK" },
200 { BSSGP_PDU_RADIO_STATUS, "RADIO-STATUS" },
201 { BSSGP_PDU_SUSPEND, "SUSPEND" },
202 { BSSGP_PDU_SUSPEND_ACK, "SUSPEND-ACK" },
203 { BSSGP_PDU_SUSPEND_NACK, "SUSPEND-NACK" },
204 { BSSGP_PDU_RESUME, "RESUME" },
205 { BSSGP_PDU_RESUME_ACK, "RESUME-ACK" },
206 { BSSGP_PDU_RESUME_NACK, "RESUME-NACK" },
207 { BSSGP_PDU_BVC_BLOCK, "BVC-BLOCK" },
208 { BSSGP_PDU_BVC_BLOCK_ACK, "BVC-BLOCK-ACK" },
209 { BSSGP_PDU_BVC_RESET, "BVC-RESET" },
210 { BSSGP_PDU_BVC_RESET_ACK, "BVC-RESET-ACK" },
211 { BSSGP_PDU_BVC_UNBLOCK, "UNBLOCK" },
212 { BSSGP_PDU_BVC_UNBLOCK_ACK, "UNBLOCK-ACK" },
213 { BSSGP_PDU_FLOW_CONTROL_BVC, "FLOW-CONTROL-BVC" },
214 { BSSGP_PDU_FLOW_CONTROL_BVC_ACK, "FLOW-CONTROL-BVC-ACK" },
215 { BSSGP_PDU_FLOW_CONTROL_MS, "FLOW-CONTROL-MS" },
216 { BSSGP_PDU_FLOW_CONTROL_MS_ACK, "FLOW-CONTROL-MS-ACK" },
217 { BSSGP_PDU_FLUSH_LL, "FLUSH-LL" },
218 { BSSGP_PDU_FLUSH_LL_ACK, "FLUSH_LL_ACK" },
219 { BSSGP_PDU_LLC_DISCARDED, "LLC-DISCARDED" },
220 { BSSGP_PDU_FLOW_CONTROL_PFC, "FLOW-CONTROL-PFC" },
221 { BSSGP_PDU_FLOW_CONTROL_PFC_ACK, "FLOW-CONTROL-PFC-ACK" },
222 { BSSGP_PDU_SGSN_INVOKE_TRACE, "SGSN-INVOKE-TRACE" },
223 { BSSGP_PDU_STATUS, "STATUS" },
224 { BSSGP_PDU_DOWNLOAD_BSS_PFC, "DOWNLOAD-BSS-PFC" },
225 { BSSGP_PDU_CREATE_BSS_PFC, "CREATE-BSS-PFC" },
226 { BSSGP_PDU_CREATE_BSS_PFC_ACK, "CREATE-BSS-PFC-ACK" },
227 { BSSGP_PDU_CREATE_BSS_PFC_NACK, "CREATE-BSS-PFC-NACK" },
228 { BSSGP_PDU_MODIFY_BSS_PFC, "MODIFY-BSS-PFC" },
229 { BSSGP_PDU_MODIFY_BSS_PFC_ACK, "MODIFY-BSS-PFC-ACK" },
230 { BSSGP_PDU_DELETE_BSS_PFC, "DELETE-BSS-PFC" },
231 { BSSGP_PDU_DELETE_BSS_PFC_ACK, "DELETE-BSS-PFC-ACK" },
232 { BSSGP_PDU_DELETE_BSS_PFC_REQ, "DELETE-BSS-PFC-REQ" },
233 { BSSGP_PDU_PERFORM_LOCATION_REQUEST, "PERFORM-LOCATION-REQUEST" },
234 { BSSGP_PDU_PERFORM_LOCATION_RESPONSE, "PERFORM-LOCATION-RESPONSE" },
235 { BSSGP_PDU_PERFORM_LOCATION_ABORT, "PERFORM-LOCATION-ABORT" },
236 { BSSGP_PDU_POSITION_COMMAND, "POSITION-COMMAND" },
237 { BSSGP_PDU_POSITION_RESPONSE, "POSITION-RESPONSE" },
238 { BSSGP_PDU_RAN_INFORMATION, "RAN-INFORMATION" },
239 { BSSGP_PDU_RAN_INFORMATION_REQUEST, "RAN-INFORMATION-REQUEST" },
240 { BSSGP_PDU_RAN_INFORMATION_ACK, "RAN-INFORMATION-ACK" },
241 { BSSGP_PDU_RAN_INFORMATION_ERROR, "RAN-INFORMATION-ERROR" },
245 /* Information element coding, v 6.5.0, table 11.3, p 72 */
246 #define BSSGP_IEI_ALIGNMENT_OCTETS 0x00
247 #define BSSGP_IEI_BMAX_DEFAULT_MS 0x01
248 #define BSSGP_IEI_BSS_AREA_INDICATION 0x02
249 #define BSSGP_IEI_BUCKET_LEAK_RATE 0x03
250 #define BSSGP_IEI_BVCI 0x04
251 #define BSSGP_IEI_BVC_BUCKET_SIZE 0x05
252 #define BSSGP_IEI_BVC_MEASUREMENT 0x06
253 #define BSSGP_IEI_CAUSE 0x07
254 #define BSSGP_IEI_CELL_IDENTIFIER 0x08
255 #define BSSGP_IEI_CHANNEL_NEEDED 0x09
256 #define BSSGP_IEI_DRX_PARAMETERS 0x0a
257 #define BSSGP_IEI_EMLPP_PRIORITY 0x0b
258 #define BSSGP_IEI_FLUSH_ACTION 0x0c
259 #define BSSGP_IEI_IMSI 0x0d
260 #define BSSGP_IEI_LLC_PDU 0x0e
261 #define BSSGP_IEI_LLC_FRAMES_DISCARDED 0x0f
262 #define BSSGP_IEI_LOCATION_AREA 0x10
263 #define BSSGP_IEI_MOBILE_ID 0x11
264 #define BSSGP_IEI_MS_BUCKET_SIZE 0x12
265 #define BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY 0x13
266 #define BSSGP_IEI_OMC_ID 0x14
267 #define BSSGP_IEI_PDU_IN_ERROR 0x15
268 #define BSSGP_IEI_PDU_LIFETIME 0x16
269 #define BSSGP_IEI_PRIORITY 0x17
270 #define BSSGP_IEI_QOS_PROFILE 0x18
271 #define BSSGP_IEI_RADIO_CAUSE 0x19
272 #define BSSGP_IEI_RA_CAP_UPD_CAUSE 0x1a
273 #define BSSGP_IEI_ROUTING_AREA 0x1b
274 #define BSSGP_IEI_R_DEFAULT_MS 0x1c
275 #define BSSGP_IEI_SUSPEND_REFERENCE_NUMBER 0x1d
276 #define BSSGP_IEI_TAG 0x1e
277 #define BSSGP_IEI_TLLI 0x1f
278 #define BSSGP_IEI_TMSI 0x20
279 #define BSSGP_IEI_TRACE_REFERENCE 0x21
280 #define BSSGP_IEI_TRACE_TYPE 0x22
281 #define BSSGP_IEI_TRANSACTION_ID 0x23
282 #define BSSGP_IEI_TRIGGER_ID 0x24
283 #define BSSGP_IEI_NUMBER_OF_OCTETS_AFFECTED 0x25
284 #define BSSGP_IEI_LSA_IDENTIFIER_LIST 0x26
285 #define BSSGP_IEI_LSA_INFORMATION 0x27
286 #define BSSGP_IEI_PFI 0x28
287 #define BSSGP_IEI_GPRS_TIMER 0x29
288 #define BSSGP_IEI_ABQP 0x3a
289 #define BSSGP_IEI_FEATURE_BITMAP 0x3b
290 #define BSSGP_IEI_BUCKET_FULL_RATIO 0x3c
291 #define BSSGP_IEI_SERVICE_UTRAN_CCO 0x3d
292 #define BSSGP_IEI_NSEI 0x3e
293 #define BSSGP_IEI_RRLP_APDU 0x3f
294 #define BSSGP_IEI_LCS_QOS 0x40
295 #define BSSGP_IEI_LCS_CLIENT_TYPE 0x41
296 #define BSSGP_IEI_REQUESTED_GPS_ASSISTANCE_DATA 0x42
297 #define BSSGP_IEI_LOCATION_TYPE 0x43
298 #define BSSGP_IEI_LOCATION_ESTIMATE 0x44
299 #define BSSGP_IEI_POSITIONING_DATA 0x45
300 #define BSSGP_IEI_DECIPHERING_KEYS 0x46
301 #define BSSGP_IEI_LCS_PRIORITY 0x47
302 #define BSSGP_IEI_LCS_CAUSE 0x48
303 #define BSSGP_IEI_LCS_CAPABILITY 0x49
304 #define BSSGP_IEI_RRLP_FLAGS 0x4a
305 #define BSSGP_IEI_RIM_APPLICATION_IDENTITY 0x4b
306 #define BSSGP_IEI_RIM_SEQUENCE_NUMBER 0x4c
307 #define BSSGP_IEI_RAN_INFORMATION_REQUEST_APPLICATION_CONTAINER 0x4d
308 #define BSSGP_IEI_RAN_INFORMATION_APPLICATION_CONTAINER 0x4e
309 #define BSSGP_IEI_RIM_PDU_INDICATIONS 0x4f
310 #define BSSGP_IEI_NUMBER_OF_CONTAINER_UNITS 0x50
311 #define BSSGP_IEI_PFC_FLOW_CONTROL_PARAMETERS 0x52
312 #define BSSGP_IEI_GLOBAL_CN_ID 0x53
313 #define BSSGP_IEI_RIM_ROUTING_INFORMATION 0x54
314 #define BSSGP_IEI_RIM_PROTOCOL_VERSION 0x55
315 #define BSSGP_IEI_APPLICATION_ERROR_CONTAINER 0x56
317 #define BSSGP_IEI_RAN_INFORMATION_REQUEST_CONTAINER_UNIT 0x57
318 #define BSSGP_IEI_RAN_INFORMATION_CONTAINER_UNIT 0x58
320 #define BSSGP_IEI_RAN_INFORMATION_APPLICATION_ERROR_CONTAINER_UNIT 0x59
321 #define BSSGP_IEI_RAN_INFORMATION_ACK_RIM_CONTAINER 0x5a
322 #define BSSGP_IEI_RAN_INFORMATION_ERROR_RIM_CONTAINER 0x5b
324 static const value_string tab_nacc_cause[]={
325 { 0x00, "Other unspecified error" },
326 { 0x01, "Syntax error in the Application Container" },
327 { 0x02, "Reporting Cell Identifier does not match with the Destination Cell Identifier or with the Source Cell Identifier" },
328 { 0x03, "SI/PSI type error" },
329 { 0x04, "Inconsistent length of a SI/PSI message" },
330 { 0x05, "Inconsistent set of messages" },
334 static const value_string tab_bssgp_ie_types[] = {
335 { BSSGP_IEI_ALIGNMENT_OCTETS, "Alignment Octets" },
336 { BSSGP_IEI_BMAX_DEFAULT_MS, "Bmax Default MS" },
337 { BSSGP_IEI_BSS_AREA_INDICATION, "BSS Area Indication" },
338 { BSSGP_IEI_BUCKET_LEAK_RATE, "Bucket Leak Rate" },
339 { BSSGP_IEI_BVCI, "BVCI" },
340 { BSSGP_IEI_BVC_BUCKET_SIZE, "BVC Bucket Size" },
341 { BSSGP_IEI_BVC_MEASUREMENT, "BVC Measurement" },
342 { BSSGP_IEI_CAUSE, "Cause" },
343 { BSSGP_IEI_CELL_IDENTIFIER, "Cell Identifier" },
344 { BSSGP_IEI_CHANNEL_NEEDED, "Channel Needed" },
345 { BSSGP_IEI_DRX_PARAMETERS, "DRX Parameters" },
346 { BSSGP_IEI_EMLPP_PRIORITY, "eMLPP Priority" },
347 { BSSGP_IEI_FLUSH_ACTION, "Flush Action" },
348 { BSSGP_IEI_IMSI, "IMSI" },
349 { BSSGP_IEI_LLC_PDU, "LLC PDU" },
350 { BSSGP_IEI_LLC_FRAMES_DISCARDED, "LLC Frames Discarded" },
351 { BSSGP_IEI_LOCATION_AREA, "Location Area" },
352 { BSSGP_IEI_MOBILE_ID, "Mobile Id" },
353 { BSSGP_IEI_MS_BUCKET_SIZE, "MS Bucket Size" },
354 { BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY, "MS Radio Access Capability" },
355 { BSSGP_IEI_OMC_ID, "OMC Id" },
356 { BSSGP_IEI_PDU_IN_ERROR, "PDU In Error" },
357 { BSSGP_IEI_PDU_LIFETIME, "PDU Lifetime" },
358 { BSSGP_IEI_PRIORITY, "Priority" },
359 { BSSGP_IEI_QOS_PROFILE, "QoS Profile" },
360 { BSSGP_IEI_RADIO_CAUSE, "Radio Cause" },
361 { BSSGP_IEI_RA_CAP_UPD_CAUSE, "RA-Cap-UPD-Cause" },
362 { BSSGP_IEI_ROUTING_AREA, "Routing Area" },
363 { BSSGP_IEI_R_DEFAULT_MS, "R_default_MS" },
364 { BSSGP_IEI_SUSPEND_REFERENCE_NUMBER, "Suspend Reference Number" },
365 { BSSGP_IEI_TAG, "Tag" },
366 { BSSGP_IEI_TLLI, "TLLI" },
367 { BSSGP_IEI_TMSI, "TMSI" },
368 { BSSGP_IEI_TRACE_REFERENCE, "Trace Reference" },
369 { BSSGP_IEI_TRACE_TYPE, "Trace Type" },
370 { BSSGP_IEI_TRANSACTION_ID, "Transaction Id" },
371 { BSSGP_IEI_TRIGGER_ID, "Trigger Id" },
372 { BSSGP_IEI_NUMBER_OF_OCTETS_AFFECTED, "Number of Octets Affected" },
373 { BSSGP_IEI_LSA_IDENTIFIER_LIST, "LSA Identifier List" },
374 { BSSGP_IEI_LSA_INFORMATION, "LSA Information" },
375 { BSSGP_IEI_PFI, "Packet Flow Identifier: " },
376 { BSSGP_IEI_GPRS_TIMER, "GPRS Timer" },
377 { BSSGP_IEI_ABQP, "ABQP" },
378 { BSSGP_IEI_FEATURE_BITMAP, "Feature Bitmap" },
379 { BSSGP_IEI_BUCKET_FULL_RATIO, "Bucket Full Ratio" },
380 { BSSGP_IEI_SERVICE_UTRAN_CCO, "Service UTRAN CCO" },
381 { BSSGP_IEI_NSEI, "NSEI" },
382 { BSSGP_IEI_RRLP_APDU, "RRLP APDU" },
383 { BSSGP_IEI_LCS_QOS, "LCS QoS" },
384 { BSSGP_IEI_LCS_CLIENT_TYPE, "LCS Client Type" },
385 { BSSGP_IEI_REQUESTED_GPS_ASSISTANCE_DATA, "Requested GPS Assistance Data" },
386 { BSSGP_IEI_LOCATION_TYPE, "Location Type" },
387 { BSSGP_IEI_LOCATION_ESTIMATE, "Location Estimate" },
388 { BSSGP_IEI_POSITIONING_DATA, "Positioning Data" },
389 { BSSGP_IEI_DECIPHERING_KEYS, "Deciphering Keys" },
390 { BSSGP_IEI_LCS_PRIORITY, "LCS Priority" },
391 { BSSGP_IEI_LCS_CAUSE, "LCS Cause" },
392 { BSSGP_IEI_LCS_CAPABILITY, "LCS Capability" },
393 { BSSGP_IEI_RRLP_FLAGS, "RRLP Flags" },
394 { BSSGP_IEI_RIM_APPLICATION_IDENTITY, "RIM Application Identity" },
395 { BSSGP_IEI_RAN_INFORMATION_APPLICATION_CONTAINER, "RAN INFORMATION Application Container" },
396 { BSSGP_IEI_RIM_SEQUENCE_NUMBER, "RIM Sequence Number" },
397 { BSSGP_IEI_RAN_INFORMATION_REQUEST_CONTAINER_UNIT, "RAN INFORMATION REQUEST RIM Container" },
398 { BSSGP_IEI_RAN_INFORMATION_CONTAINER_UNIT, "RAN INFORMATION RIM Container" },
399 { BSSGP_IEI_RIM_PDU_INDICATIONS, "RIM PDU Indications" },
400 { BSSGP_IEI_RIM_PROTOCOL_VERSION, "RIM Protocol Version Number" },
401 { BSSGP_IEI_NUMBER_OF_CONTAINER_UNITS, "Number of Container Units" },
402 { BSSGP_IEI_PFC_FLOW_CONTROL_PARAMETERS, "PFC Flow Control Parameters" },
403 { BSSGP_IEI_GLOBAL_CN_ID, "Global CN Id" },
407 /* Presence requirements of Information Elements
408 48.016 v 5.3.0, chapter 8.1.1, p. 35 */
409 #define BSSGP_IE_PRESENCE_M 1 /* Mandatory */
410 #define BSSGP_IE_PRESENCE_O 2 /* Conditional */
411 #define BSSGP_IE_PRESENCE_C 3 /* Optional */
414 #define BSSGP_IE_FORMAT_V 1
415 #define BSSGP_IE_FORMAT_TV 2
416 #define BSSGP_IE_FORMAT_TLV 3
420 get_masked_guint8(guint8 value, guint8 mask) {
421 const guint8 MASK_BIT_1 = 0x01;
424 while (!((mask >> i) & MASK_BIT_1)) {
428 return (value & mask) >> i;
433 get_masked_guint16(guint16 value, guint16 mask) {
434 const guint16 MASK_BIT_1 = 0x01;
437 while (!((mask >> i) & MASK_BIT_1)) {
439 if (i > 15) return 0;
441 return (value & mask) >> i;
446 make_mask32(guint8 num_bits, guint8 shift_value) {
447 const guint32 LEFT_MOST_1 = 0x80000000;
449 guint32 mask = LEFT_MOST_1;
451 for (i = 0; i < (num_bits - 1); i++) {
452 mask = (mask >> 1) | LEFT_MOST_1;
454 return mask >> shift_value;
458 get_masked_guint32(guint32 value, guint32 mask) {
459 const guint16 MASK_BIT_1 = 0x01;
462 while (!((mask >> i) & MASK_BIT_1)) {
464 if (i > 31) return 0;
466 return (value & mask) >> i;
470 tvb_get_masked_guint8(tvbuff_t *tvb, int offset, guint8 mask) {
471 guint8 value = tvb_get_guint8(tvb, offset);
472 return get_masked_guint8(value, mask);
476 get_bit_field_label(guint16 value, guint16 value_mask, guint16 num_bits) {
477 #define MAX_NUM_BITS 16
479 static char label[MAX_NUM_BITS + 1];
481 DISSECTOR_ASSERT(num_bits <= MAX_NUM_BITS);
482 for (i = 0; i < num_bits; i++) {
484 if (value_mask & bit_mask) {
485 label[num_bits - 1 - i] = (value & bit_mask) ? '1' : '0';
488 label[num_bits - 1 - i] = '.';
496 get_bit_field_label8(guint8 value, guint8 value_mask) {
498 static char formatted_label[10];
499 bits = get_bit_field_label(value, value_mask, 8);
500 g_snprintf(formatted_label, 10, "%c%c%c%c %c%c%c%c",
501 bits[0], bits[1], bits[2], bits[3],
502 bits[4], bits[5], bits[6], bits[7]);
503 return formatted_label;
507 get_bit_field_label16(guint16 value, guint16 value_mask) {
509 static char formatted_label[18];
510 bits = get_bit_field_label(value, value_mask, 16);
511 g_snprintf(formatted_label, 18, "%c%c%c%c%c%c%c%c %c%c%c%c%c%c%c%c",
512 bits[0], bits[1], bits[2], bits[3],
513 bits[4], bits[5], bits[6], bits[7],
514 bits[8], bits[9], bits[10], bits[11],
515 bits[12], bits[13], bits[14], bits[15]);
516 return formatted_label;
520 proto_tree_add_bitfield8(proto_tree *tree, tvbuff_t *tvb, int offset, guint8 mask) {
521 /* XXX: Use varargs */
522 guint8 value = tvb_get_guint8(tvb, offset);
523 char *label = get_bit_field_label8(value, mask);
524 proto_item *pi = proto_tree_add_text(tree, tvb, offset, 1, "%s = ",
531 proto_tree_add_bitfield16(proto_tree *tree, tvbuff_t *tvb, int offset, guint16 mask) {
532 /* XXX: Use varargs */
533 guint16 value = tvb_get_ntohs(tvb, offset);
534 char *label = get_bit_field_label16(value, mask);
535 proto_item *pi = proto_tree_add_text(tree, tvb, offset, 2, "%s = ",
542 get_byte_offset(guint64 bo) {
543 return (guint8) bo % 8;
547 get_start_octet(guint64 bo) {
548 return (guint32) floor((gint64)bo / 8.0);
552 get_end_octet(guint64 bo, guint32 bl)
554 return (guint32) ceil((gint64)(bo + bl) / 8.0);
558 get_num_octets_spanned(guint64 bo, guint32 bl)
560 return get_end_octet(bo, bl) - get_start_octet(bo);
564 make_mask(guint8 num_bits, guint8 shift_value) {
568 case 0: mask = 0x0000; break;
569 case 1: mask = 0x8000; break;
570 case 2: mask = 0xc000; break;
571 case 3: mask = 0xe000; break;
572 case 4: mask = 0xf000; break;
573 case 5: mask = 0xf800; break;
574 case 6: mask = 0xfc00; break;
575 case 7: mask = 0xfe00; break;
576 case 8: mask = 0xff00; break;
577 default: DISSECTOR_ASSERT_NOT_REACHED(); mask = 0; break;
579 return mask >> shift_value;
583 bssgp_tvb_get_bits8(tvbuff_t *tvb, guint64 bo, guint8 num_bits) {
584 /* Returns 0-8 bits from tvb */
588 shift_value = get_byte_offset(bo);
589 mask = make_mask(num_bits, shift_value);
590 if (( mask & 0xff ) == 0 ) data = tvb_get_guint8(tvb, get_start_octet(bo)) << 8;
591 else data = tvb_get_ntohs(tvb, get_start_octet(bo));
592 return (data & mask) >> (16 - shift_value - num_bits);
596 bit_proto_tree_add_text(proto_tree *tree, tvbuff_t *tvb,
597 guint64 bo, guint8 bl, const char *value) {
598 /* XXX: Use varargs */
599 return proto_tree_add_text(tree, tvb, get_start_octet(bo),
600 get_num_octets_spanned(bo, bl), "%s", value);
604 bit_proto_tree_add_bit_field8(proto_tree *tree, tvbuff_t *tvb,
605 guint64 bo, guint8 bl) {
606 /* XXX: Use varargs */
607 guint16 mask = make_mask(bl, get_byte_offset(bo));
613 if (( mask & 0xff ) == 0 ) value = tvb_get_guint8 ( tvb , get_start_octet(bo)) << 8;
614 else value = tvb_get_ntohs(tvb, get_start_octet(bo));
615 label = get_bit_field_label16(value, mask);
617 DISSECTOR_ASSERT(bl < 9);
619 if (get_num_octets_spanned(bo, bl) == 1) {
625 pi = bit_proto_tree_add_text(tree, tvb, bo, bl, "");
627 for (i = 0; i <=end_i; i++) {
628 proto_item_append_text(pi, "%c", label[i]);
630 proto_item_append_text(pi, " = ");
635 translate_abqp_reliability_class(guint8 value, build_info_t *bi) {
639 return "Subscribed reliability class";
645 return "Unused (Unacknowledged GTP; Acknowledged LLc and RLC, Protected data)";
647 return "Unacknowledged GTP; Acknowledged LLc and RLC, Protected data";
649 return "Unacknowledged GTP and LLC; Acknowledged RLC, Protected data";
651 return "Unacknowledged GTP, LLC, and RLC, Protected data";
653 return "Unacknowledged GTP, LLC, and RLC, Unprotedcted data";
657 return "Unacknowledged GTP and LLC; Acknowledged RLC, Protected data";
661 translate_abqp_delay_class(guint8 value, build_info_t *bi) {
665 return "Subscribed delay class";
670 case 1: return "Delay class 1";
671 case 2: return "Delay class 2";
672 case 3: return "Delay class 3";
673 case 4: return "Delay class 4 (best effort)";
674 case 7: return "Reserved";
676 return "Delay class 4 (best effort)";
680 translate_abqp_peak_throughput(guint8 value, build_info_t *bi) {
684 return "Subscribed peak throughput";
689 case 1: return "Up to 1 000 octets/s";
690 case 2: return "Up to 2 000 octets/s";
691 case 3: return "Up to 4 000 octets/s";
692 case 4: return "Up to 8 000 octets/s";
693 case 5: return "Up to 16 000 octets/s";
694 case 6: return "Up to 32 000 octets/s";
695 case 7: return "Up to 64 000 octets/s";
696 case 8: return "Up to 128 000 octets/s";
697 case 9: return "Up to 256 000 octets/s";
698 case 15: return "Reserved";
700 return "Up to 1 000 octets/s";
704 translate_abqp_precedence_class(guint8 value, build_info_t *bi) {
708 return "Subscribed precedence";
713 case 1: return "High priority";
714 case 2: return "Normal priority";
715 case 3: return "Low priority";
716 case 7: return "Reserved";
718 return "Normal priority";
722 translate_abqp_mean_throughput(guint8 value, build_info_t *bi) {
726 return "Subscribed mean throughput";
731 case 1: return "100 octets/h";
732 case 2: return "200 octets/h";
733 case 3: return "500 octets/h";
734 case 4: return "1 000 octets/h";
735 case 5: return "2 000 octets/h";
736 case 6: return "5 000 octets/h";
737 case 7: return "10 000 octets/h";
738 case 8: return "20 000 octets/h";
739 case 9: return "50 000 octets/h";
740 case 0x0a: return "100 000 octets/h";
741 case 0x0b: return "200 000 octets/h";
742 case 0x0c: return "500 000 octets/h";
743 case 0x0d: return "1 000 000 octets/h";
744 case 0x0e: return "2 000 000 octets/h";
745 case 0x0f: return "5 000 000 octets/h";
746 case 0x10: return "10 000 000 octets/h";
747 case 0x11: return "20 000 000 octets/h";
748 case 0x12: return "50 000 000 octets/h";
749 case 0x1e: return "Reserved";
750 case 0x1f: return "Best effort";
752 return "Best effort";
756 translate_abqp_traffic_class(guint8 value, build_info_t *bi) {
760 return "Subscribed traffic class";
765 case 1: return "Conversational class";
766 case 2: return "Streaming class";
767 case 3: return "Interactive class";
768 case 4: return "Background class";
769 case 7: return "Reserved";
772 /* The MS shall consider all other values as reserved */
776 /* The network shall map all other values not explicitly defined onto one of the values defined in this version of the protocol. The network shall return a negotiated value which is explicitly defined in this version of the protocol */
782 translate_abqp_delivery_order(guint8 value, build_info_t *bi) {
786 return "Subscribed delivery order";
791 case 1: return "With delivery order ('yes')";
792 case 2: return "Without delivery order ('no')";
793 case 3: return "Reserved";
795 return "Error in BSSGP dissector";
799 translate_abqp_delivery_of_erroneous_sdu(guint8 value, build_info_t *bi) {
803 return "Subscribed delivery of erroneous SDUs";
808 case 1: return "No detect ('-')";
809 case 2: return "Erroneous SDUs are delivered ('yes')";
810 case 3: return "Erroneous SDUs are not delivered ('no')";
811 case 7: return "Reserved";
814 /* The MS shall consider all other values as reserved */
818 /* The network shall map all other values not explicitly defined onto one of the values defined in this version of the protocol. The network shall return a negotiated value which is explicitly defined in this version of the protocol */
824 translate_abqp_max_sdu_size(guint8 value, build_info_t *bi) {
825 static char result[BSSGP_TRANSLATION_MAX_LEN];
830 return "Subscribed maximum SDU size";
842 case 0x97: return "1502 octets";
843 case 0x98: return "1510 octets";
844 case 0x99: return "1520 octets";
846 if ((value >= 1) && (value <= 0x96)) {
847 g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u octets", value * 10);
851 /* The MS shall consider all other values as reserved */
855 /* The network shall map all other values not explicitly defined onto one of the values defined in this version of the protocol. The network shall return a negotiated value which is explicitly defined in this version of the protocol */
861 translate_abqp_max_bit_rate_for_ul(guint8 value, build_info_t *bi) {
862 static char result[BSSGP_TRANSLATION_MAX_LEN];
866 return "Subscribed maximum bit rate for uplink";
872 if ((value >= 1) && (value <= 0x3f)) {
873 g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u kbps", value);
876 if ((value >= 0x40) && (value <= 0x7f)) {
877 g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u kbps", 64 + (value - 0x40) * 8);
880 if ((value >= 0x80) && (value <= 0xfe)) {
881 g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u kbps", 576 + (value - 0x80) * 64);
888 translate_abqp_max_bit_rate_for_dl(guint8 value, build_info_t *bi) {
889 return translate_abqp_max_bit_rate_for_ul(value, bi);
893 translate_abqp_residual_ber(guint8 value, build_info_t *bi) {
897 return "Subscribed residual BER";
902 case 1: return "5*10^-2";
903 case 2: return "1*10^-2";
904 case 3: return "5*10^-3";
905 case 4: return "4*10^-3";
906 case 5: return "1*10^-3";
907 case 6: return "1*10^-4";
908 case 7: return "1*10^-5";
909 case 8: return "1*10^-6";
910 case 9: return "6*10^-8";
911 case 15: return "Reserved";
914 /* The MS shall consider all other values as reserved */
918 /* The network shall map all other values not explicitly defined onto one of the values defined in this version of the protocol. The network shall return a negotiated value which is explicitly defined in this version of the protocol */
924 translate_abqp_sdu_error_ratio(guint8 value, build_info_t *bi) {
928 return "Subscribed SDU error ratio";
933 case 1: return "1*10^-2";
934 case 2: return "7*10^-3";
935 case 3: return "1*10^-3";
936 case 4: return "1*10^-4";
937 case 5: return "1*10^-5";
938 case 6: return "1*10^-6";
939 case 7: return "1*10^-1";
940 case 15: return "Reserved";
943 /* The MS shall consider all other values as reserved */
947 /* The network shall map all other values not explicitly defined onto one of the values defined in this version of the protocol. The network shall return a negotiated value which is explicitly defined in this version of the protocol */
953 translate_abqp_transfer_delay(guint8 value, build_info_t *bi) {
954 static char result[BSSGP_TRANSLATION_MAX_LEN];
958 return "Subscribed transfer delay";
964 if ((value >= 1) && (value <= 0x0f)) {
965 g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u ms", value * 10);
968 if ((value >= 0x10) && (value <= 0x1f)) {
969 g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u ms", 200 + (value - 0x10) * 50);
972 if ((value >= 0x20) && (value <= 0x3e)) {
973 g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u ms", 1000 + (value - 0x20) * 100);
980 translate_abqp_traffic_handling_priority(guint8 value, build_info_t *bi) {
984 return "Subscribed traffic handling_priority";
989 case 1: return "Priority level 1";
990 case 2: return "Priority level 2";
991 case 3: return "Priority level 3";
997 translate_abqp_guaranteed_bit_rate_for_ul(guint8 value, build_info_t *bi) {
998 return translate_abqp_max_bit_rate_for_ul(value, bi);
1001 translate_abqp_guaranteed_bit_rate_for_dl(guint8 value, build_info_t *bi) {
1002 return translate_abqp_max_bit_rate_for_ul(value, bi);
1006 translate_abqp_source_statistics_descriptor(guint8 value, build_info_t *bi) {
1009 case 0: return "Unknown";
1010 case 1: return "Speech";
1011 default: return "Unknown";
1020 translate_abqp_max_bit_rate_for_dl_extended(guint8 value, build_info_t *bi _U_) {
1021 static char result[BSSGP_TRANSLATION_MAX_LEN];
1024 return "Use the value indicated by the Maximum bit rate for downlink";
1026 if ((value >= 1) && (value <= 0x4a)) {
1027 g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u kbps", 8600 + value * 100);
1030 /* The network shall map all other values not explicitly defined onto one of the values defined in this version of the protocol. The network shall return a negotiated value which is explicitly defined in this version of the protocol */
1035 translate_abqp_guaranteed_bit_rate_for_dl_extended(guint8 value, build_info_t *bi _U_) {
1036 static char result[BSSGP_TRANSLATION_MAX_LEN];
1039 return "Use the value indicated by the Guaranteed bit rate for downlink";
1041 if ((value >= 1) && (value <= 0x4a)) {
1042 g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u kbps", 8600 + value * 100);
1045 /* The network shall map all other values not explicitly defined onto one of the values defined in this version of the protocol. The network shall return a negotiated value which is explicitly defined in this version of the protocol */
1050 translate_msrac_access_technology_type(guint8 value) {
1051 static const value_string tab_values[] = {
1062 { 10, "GSM T 410" },
1063 { 11, "GSM T 900" },
1064 { 15, "List of Additional Access Technologies present" },
1066 /* Otherwise "Unknown" */
1068 return val_to_str(value, tab_values, "Unknown");
1072 translate_msrac_dtm_gprs_multislot_class(guint8 value) {
1073 static const value_string tab_values[] = {
1074 { 0, "Unused, interpreted as \"Multislot class 5 supported\"" },
1075 { 1, "Multislot class 5 supported" },
1076 { 2, "Multislot class 9 supported" },
1077 { 3, "Multislot class 11 supported" },
1079 /* No other combinations*/
1081 return val_to_str(value, tab_values, "");
1085 translate_msrac_extended_dtm_gprs_multislot_class(guint8 value, guint8 dgmsc) {
1087 case 0: return "Unused, interpreted as Multislot class 5 supported";
1090 case 0: return "Multislot class 5 supported";
1091 case 1: return "Multislot class 6 supported";
1094 return "Unused, interpreted as Multislot class 5 supported";
1098 case 0: return "Multislot class 9 supported";
1099 case 1: return "Multislot class 10 supported";
1102 return "Unused, interpreted as Multislot class 5 supported";
1106 case 0: return "Multislot class 11 supported";
1110 return "Unused, interpreted as Multislot class 5 supported";
1113 DISSECTOR_ASSERT_NOT_REACHED();
1114 return "Error"; /* Dummy */
1119 translate_msrac_high_multislot_capability(guint8 capability, guint8 class) {
1120 switch (capability) {
1210 DISSECTOR_ASSERT_NOT_REACHED();
1216 translate_channel_needed(guint8 value) {
1218 case 0: return "Any channel";
1219 case 1: return "SDCCH";
1220 case 2: return "TCH/F (Full rate)";
1221 case 3: return "TCH/H or TCH/F (Dual rate)";
1223 DISSECTOR_ASSERT_NOT_REACHED();
1228 bssgp_proto_tree_add_ie(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1233 iename = val_to_str(ie->iei, tab_bssgp_ie_types, "Unknown");
1234 return proto_tree_add_uint_format(bi->bssgp_tree, hf_bssgp_ie_type,
1235 bi->tvb, ie_start_offset, ie->total_length,
1236 ie->iei, "%s", iename);
1240 bssgp_proto_handoff(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset, dissector_handle_t handle) {
1241 tvbuff_t *next_tvb=NULL;
1243 if(ie->value_length > 0)
1244 next_tvb = tvb_new_subset(bi->tvb, bi->offset, -1, -1);
1246 if (bi->bssgp_tree) {
1247 bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1251 call_dissector(handle, next_tvb, bi->pinfo, bi->parent_tree);
1253 else if (data_handle) {
1254 call_dissector(data_handle, next_tvb, bi->pinfo, bi->parent_tree);
1260 decode_nri(proto_tree *tf, build_info_t *bi, guint32 tmsi_tlli) {
1261 proto_item *hidden_item;
1262 const guint32 LOCAL_TLLI_MASK = 0xc0000000;
1263 const guint32 FOREIGN_TLLI_MASK = 0x80000000;
1266 if (bssgp_decode_nri && (bssgp_nri_length != 0) &&
1267 (((tmsi_tlli & LOCAL_TLLI_MASK) == LOCAL_TLLI_MASK) ||
1268 ((tmsi_tlli & FOREIGN_TLLI_MASK) == FOREIGN_TLLI_MASK))) {
1269 nri = get_masked_guint32(tmsi_tlli, make_mask32( (guint8) bssgp_nri_length, 8));
1271 hidden_item = proto_tree_add_uint(tf, hf_bssgp_nri, bi->tvb, bi->offset, 4, nri);
1272 PROTO_ITEM_SET_HIDDEN(hidden_item);
1274 if (check_col(bi->pinfo->cinfo, COL_INFO)) {
1275 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP, "NRI %u", nri);
1281 decode_mobile_identity(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1282 #define MAX_NUM_IMSI_DIGITS 15
1283 const guint8 MASK_ODD_EVEN_INDICATION = 0x08;
1284 const guint8 MASK_TYPE_OF_IDENTITY = 0x07;
1285 const guint8 ODD = 1;
1286 proto_item *ti = NULL, *pi;
1287 proto_tree *tf = NULL;
1288 guint8 data, odd_even, type, num_digits, i;
1291 guint8 digits[MAX_NUM_IMSI_DIGITS];
1292 char digits_str[MAX_NUM_IMSI_DIGITS + 1];
1294 static const value_string tab_type_of_identity[] = {
1295 { BSSGP_MOBILE_IDENTITY_TYPE_IMSI, "IMSI" },
1296 { BSSGP_MOBILE_IDENTITY_TYPE_IMEI, "IMEI" },
1297 { BSSGP_MOBILE_IDENTITY_TYPE_IMEISV, "IMEISV" },
1298 { BSSGP_MOBILE_IDENTITY_TYPE_TMSI_PTMSI, "TMSI//P-TMSI" },
1299 { BSSGP_MOBILE_IDENTITY_TYPE_NO_IDENTITY, "No identity" },
1301 /* Otherwise "Reserved" */
1304 digits_str[0] = '\0'; /* conceivably num_digits below could be zero */
1306 if (bi->bssgp_tree) {
1307 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1308 tf = proto_item_add_subtree(ti, ett_bssgp_mobile_identity);
1310 data = tvb_get_guint8(bi->tvb, bi->offset);
1311 odd_even = get_masked_guint8(data, MASK_ODD_EVEN_INDICATION);
1313 if (bi->bssgp_tree) {
1314 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
1315 MASK_ODD_EVEN_INDICATION);
1316 proto_item_append_text(pi, "Odd/Even Indication: %s number of identity digits%s",
1317 odd_even == ODD ? "Odd" : "Even",
1318 odd_even == ODD ? "" : " and also when the TMSI/P_TMSI is used");
1320 type = get_masked_guint8(data, MASK_TYPE_OF_IDENTITY);
1322 if (bi->bssgp_tree) {
1323 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
1324 MASK_TYPE_OF_IDENTITY);
1325 proto_item_append_text(pi, "Type of Identity: %s",
1326 val_to_str(type, tab_type_of_identity,
1331 case BSSGP_MOBILE_IDENTITY_TYPE_IMSI:
1332 case BSSGP_MOBILE_IDENTITY_TYPE_IMEI:
1333 case BSSGP_MOBILE_IDENTITY_TYPE_IMEISV:
1334 num_digits = 1 + (ie->value_length - 1) * 2;
1335 if (odd_even != ODD ) num_digits--;
1336 if (num_digits > MAX_NUM_IMSI_DIGITS) THROW(ReportedBoundsError);
1339 digits[i] = get_masked_guint8(data, BSSGP_MASK_LEFT_OCTET_HALF);
1343 data = tvb_get_guint8(bi->tvb, bi->offset);
1345 digits[i] = get_masked_guint8(data, BSSGP_MASK_RIGHT_OCTET_HALF);
1347 if (i >= num_digits) break;
1349 digits[i] = get_masked_guint8(data, BSSGP_MASK_LEFT_OCTET_HALF);
1351 if (i >= num_digits) break;
1356 if (bi->bssgp_tree) {
1357 proto_item_append_text(ti, ": ");
1358 for (i = 0; i < num_digits; i++) {
1359 proto_item_append_text(ti, "%u", digits[i]);
1360 g_snprintf(&digits_str[i], 2, "%u", digits[i]);
1363 case BSSGP_MOBILE_IDENTITY_TYPE_IMSI:
1364 hf_id = hf_bssgp_imsi;
1366 case BSSGP_MOBILE_IDENTITY_TYPE_IMEI:
1367 hf_id = hf_bssgp_imei;
1369 case BSSGP_MOBILE_IDENTITY_TYPE_IMEISV:
1370 hf_id = hf_bssgp_imeisv;
1373 DISSECTOR_ASSERT_NOT_REACHED();
1378 proto_tree_add_string(tf, hf_id, bi->tvb, ie_start_offset + 2, ((num_digits/2)+1), digits_str);
1381 if (check_col(bi->pinfo->cinfo, COL_INFO)) {
1382 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP, "%s %s",
1383 val_to_str(type, tab_type_of_identity,
1384 "Mobile identity unknown"),
1388 case BSSGP_MOBILE_IDENTITY_TYPE_TMSI_PTMSI:
1389 tmsi = tvb_get_ntohl(bi->tvb, bi->offset);
1390 if (check_col(bi->pinfo->cinfo, COL_INFO)) {
1391 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP,
1392 "TMSI/P-TMSI %0x04x", tmsi);
1394 if (bi->bssgp_tree) {
1395 proto_tree_add_item(tf, hf_bssgp_tmsi_ptmsi, bi->tvb, bi->offset, 4,
1396 BSSGP_LITTLE_ENDIAN);
1397 proto_item_append_text(ti, ": %#04x", tmsi);
1399 decode_nri(tf, bi, tmsi);
1405 #undef MAX_NUM_IMSI_DIGITS
1409 decode_mcc_mnc(build_info_t *bi, proto_tree *parent_tree) {
1411 const guint8 UNUSED_MNC3 = 0x0f;
1412 guint8 mcc1, mcc2, mcc3, mnc1, mnc2, mnc3, data;
1413 guint16 start_offset, mcc, mnc;
1414 static char mcc_mnc[RES_LEN];
1416 start_offset = bi->offset;
1419 data = tvb_get_guint8(bi->tvb, bi->offset);
1420 mcc2 = get_masked_guint8(data, BSSGP_MASK_LEFT_OCTET_HALF);
1421 mcc1 = get_masked_guint8(data, BSSGP_MASK_RIGHT_OCTET_HALF);
1424 data = tvb_get_guint8(bi->tvb, bi->offset);
1425 mnc3 = get_masked_guint8(data, BSSGP_MASK_LEFT_OCTET_HALF);
1426 mcc3 = get_masked_guint8(data, BSSGP_MASK_RIGHT_OCTET_HALF);
1429 data = tvb_get_guint8(bi->tvb, bi->offset);
1430 mnc2 = get_masked_guint8(data, BSSGP_MASK_LEFT_OCTET_HALF);
1431 mnc1 = get_masked_guint8(data, BSSGP_MASK_RIGHT_OCTET_HALF);
1434 /* XXX: If mxci out of range the ms should transmit the values using full hexademical encoding? */
1436 /* XXX: Interpretation of mcci? */
1437 mcc = 100 * mcc1 + 10 * mcc2 + mcc3;
1439 /* XXX: Interpretation of mnci? */
1440 mnc = 10 * mnc1 + mnc2;
1442 if (mnc3 != UNUSED_MNC3) {
1443 mnc += 10 * mnc + mnc3;
1446 proto_tree_add_uint(parent_tree, hf_bssgp_mcc,
1447 bi->tvb, start_offset, 3, mcc);
1448 proto_tree_add_uint(parent_tree, hf_bssgp_mnc,
1449 bi->tvb, start_offset, 3, mnc);
1451 if (mnc3 != UNUSED_MNC3) {
1452 /* Three digits mnc */
1453 g_snprintf(mcc_mnc, RES_LEN, "%u-%03u", mcc, mnc);
1456 /* Two digits mnc */
1457 g_snprintf(mcc_mnc, RES_LEN, "%u-%02u", mcc, mnc);
1464 decode_lai(build_info_t *bi, proto_tree *parent_tree) {
1468 static char lai[RES_LEN];
1470 mcc_mnc = decode_mcc_mnc(bi, parent_tree);
1472 lac = tvb_get_ntohs(bi->tvb, bi->offset);
1473 proto_tree_add_item(parent_tree, hf_bssgp_lac,
1474 bi->tvb, bi->offset, 2, BSSGP_LITTLE_ENDIAN);
1477 g_snprintf(lai, RES_LEN, "%s-%u", mcc_mnc, lac);
1483 decode_rai(build_info_t *bi, proto_tree *parent_tree) {
1486 static char rai[RES_LEN];
1487 char *lai = decode_lai(bi, parent_tree);
1489 rac = tvb_get_guint8(bi->tvb, bi->offset);
1490 proto_tree_add_item(parent_tree, hf_bssgp_rac, bi->tvb, bi->offset, 1, BSSGP_LITTLE_ENDIAN);
1493 g_snprintf(rai, RES_LEN, "%s-%u", lai, rac);
1499 decode_rai_ci(build_info_t *bi, proto_tree *parent_tree) {
1502 static char rai_ci[RES_LEN];
1505 rai = decode_rai(bi, parent_tree);
1507 ci = tvb_get_ntohs(bi->tvb, bi->offset);
1508 proto_tree_add_item(parent_tree, hf_bssgp_ci,
1509 bi->tvb, bi->offset, 2, BSSGP_LITTLE_ENDIAN);
1511 g_snprintf(rai_ci, RES_LEN, "RAI %s, CI %u", rai, ci);
1517 bssgp_pi_append_queuing_delay(proto_item *pi, tvbuff_t *tvb, int offset) {
1518 const guint16 INFINITE_DELAY = 0xffff;
1519 guint16 value = tvb_get_ntohs(tvb, offset);
1520 if (value == INFINITE_DELAY) {
1521 proto_item_append_text(pi, ": Infinite delay (%#4x)", value);
1524 proto_item_append_text(pi, ": %u centi-seconds delay", value);
1529 bssgp_pi_append_bucket_leak_rate(proto_item *pi, tvbuff_t *tvb, int offset) {
1530 guint16 value = tvb_get_ntohs(tvb, offset);
1531 proto_item_append_text(pi, ": %u bits", value * 100);
1535 bssgp_pi_append_bucket_size(proto_item *pi, tvbuff_t *tvb, int offset) {
1536 guint16 value = tvb_get_ntohs(tvb, offset);
1537 proto_item_append_text(pi, ": %u bytes", value * 100);
1541 bssgp_pi_append_bucket_full_ratio(proto_item *pi, tvbuff_t *tvb, int offset) {
1542 guint8 value = tvb_get_guint8(tvb, offset);
1543 proto_item_append_text(pi, ": %.2f * Bmax ", value / 100.0);
1547 bssgp_pi_append_pfi(proto_item *pi, tvbuff_t *tvb, int offset) {
1548 const guint8 MASK_PFI = 0x7f;
1551 static const value_string tab_pfi[] = {
1552 { 0, "Best effort" },
1561 /* Otherwise "Dynamically assigned (PFI: <value>)" */
1563 value = tvb_get_masked_guint8(tvb, offset, MASK_PFI);
1564 proto_item_append_text(pi,
1565 "%s", val_to_str(value, tab_pfi, "Dynamically assigned (PFI: %d)"));
1569 decode_pfi(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1571 if (bi->bssgp_tree) {
1572 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1573 bssgp_pi_append_pfi(ti, bi->tvb, bi->offset);
1575 bi->offset += ie->value_length;
1579 decode_queuing_delay(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1581 if (bi->bssgp_tree) {
1582 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1583 bssgp_pi_append_queuing_delay(ti, bi->tvb, bi->offset);
1585 bi->offset += ie->value_length;
1589 decode_bucket_size(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1591 if (bi->bssgp_tree) {
1592 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1593 bssgp_pi_append_bucket_size(ti, bi->tvb, bi->offset);
1595 bi->offset += ie->value_length;
1599 decode_bucket_leak_rate(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1601 if (bi->bssgp_tree) {
1602 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1603 bssgp_pi_append_bucket_leak_rate(ti, bi->tvb, bi->offset);
1605 bi->offset += ie->value_length;
1609 get_value_length(bssgp_ie_t *ie, build_info_t *bi) {
1610 /* length indicator in bit 8, 0 => two bytes, 1 => one byte */
1611 const guint8 MASK_LENGTH_INDICATOR = 0x80;
1612 const guint8 MASK_ONE_BYTE_LENGTH = 0x7f;
1616 length = tvb_get_guint8(bi->tvb, bi->offset);
1619 if (length & MASK_LENGTH_INDICATOR) {
1620 length &= MASK_ONE_BYTE_LENGTH;
1625 length |= tvb_get_guint8(bi->tvb, bi->offset+1);
1627 ie->value_length = length;
1628 ie->total_length += length_len + length;
1629 bi->offset += length_len;
1633 decode_simple_ie(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset,
1634 const char *pre_str, const char *post_str,
1635 gboolean show_as_dec) {
1636 /* XXX: Allow mask? */
1640 switch (ie->value_length) {
1641 case 1: value = tvb_get_guint8(bi->tvb, bi->offset); break;
1642 case 2: value = tvb_get_ntohs(bi->tvb, bi->offset); break;
1643 case 3: value = tvb_get_ntoh24(bi->tvb, bi->offset); break;
1644 case 4: value = tvb_get_ntohl(bi->tvb, bi->offset); break;
1645 default: value = 0; break;
1648 if (bi->bssgp_tree) {
1649 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1651 proto_item_append_text(ti, ": ");
1654 proto_item_append_text(ti, "%s ", pre_str);
1657 proto_item_append_text(ti, "%u", value);
1660 switch (ie->value_length) {
1661 case 1: proto_item_append_text(ti, "%#1x", value); break;
1662 case 2: proto_item_append_text(ti, "%#2x", value); break;
1663 case 3: proto_item_append_text(ti, "%#3x", value); break;
1664 case 4: proto_item_append_text(ti, "%#4x", value); break;
1668 proto_item_append_text(ti, " %s", post_str);
1670 bi->offset += ie->value_length;
1674 check_correct_iei(bssgp_ie_t *ie, build_info_t *bi) {
1675 guint8 fetched_iei = tvb_get_guint8(bi->tvb, bi->offset);
1678 if (fetched_iei != ie->iei) {
1679 proto_tree_add_text(bi->bssgp_tree, bi->tvb, bi->offset, 1,
1680 "Tried IEI %s (%#02x), found IEI %s (%#02x)",
1681 val_to_str(ie->iei, tab_bssgp_ie_types, "Unknown"),
1683 val_to_str(fetched_iei, tab_bssgp_ie_types, "Unknown"),
1687 return (fetched_iei == ie->iei);
1691 decode_iei_alignment_octets(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1693 if (bi->bssgp_tree) {
1694 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1695 proto_item_append_text(ti, " (%u bytes)", ie->value_length);
1697 bi->offset += ie->value_length;
1701 decode_iei_bvci(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1702 proto_item *ti, *hidden_item;
1705 bvci = tvb_get_ntohs(bi->tvb, bi->offset);
1707 if (bi->bssgp_tree) {
1708 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1709 proto_item_append_text(ti, ": %u", bvci);
1710 hidden_item = proto_tree_add_item(bi->bssgp_tree, hf_bssgp_bvci,
1711 bi->tvb, bi->offset, ie->value_length,
1712 BSSGP_LITTLE_ENDIAN);
1713 PROTO_ITEM_SET_HIDDEN(hidden_item);
1715 bi->offset += ie->value_length;
1717 if (check_col(bi->pinfo->cinfo, COL_INFO)) {
1718 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP,
1723 const value_string tab_cause[] = {
1724 { 0x00, "Processor overload" },
1725 { 0x01, "Equipment failure" },
1726 { 0x02, "Transit network service failure" },
1727 { 0x03, "Network service transmission capacity modified from zero kbps to greater than zero kbps" },
1728 { 0x04, "Unknown MS" },
1729 { 0x05, "BVCI unknown" },
1730 { 0x06, "Cell traffic congestion" },
1731 { 0x07, "SGSN congestion" },
1732 { 0x08, "O&M intervention" },
1733 { 0x09, "BVCI blocked" },
1734 { 0x0a, "PFC create failure" },
1735 { 0x0b, "PFC preempted" },
1736 { 0x0c, "ABQP no more supported" },
1737 { 0x20, "Semantically incorrect PDU" },
1738 { 0x21, "Invalid mandatory information" },
1739 { 0x22, "Missing mandatory IE" },
1740 { 0x23, "Missing conditional IE" },
1741 { 0x24, "Unexpected conditional IE" },
1742 { 0x25, "Conditional IE error" },
1743 { 0x26, "PDU not compatible with the protocol state" },
1744 { 0x27, "Protocol error - unspecified" },
1745 { 0x28, "PDU not compatible with the feature set" },
1746 { 0x29, "Requested information not available" },
1747 { 0x2a, "Unknown destination address" },
1748 { 0x2b, "Unknown RIM application identity" },
1749 { 0x2c, "Invalid container unit information" },
1750 { 0x2d, "PFC queuing" },
1751 { 0x2e, "PFC created successfully" },
1756 decode_iei_cause(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1761 if (bi->bssgp_tree) {
1762 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1763 value = tvb_get_guint8(bi->tvb, bi->offset);
1764 proto_item_append_text(ti, ": %s (%#02x)",
1765 val_to_str(value, tab_cause,
1766 "Protocol error - unspecified"),
1769 bi->offset += ie->value_length;
1773 * 11.3.9 Cell Identifier 3GPP TS 48.018 version 6.7.0 Release 6
1776 decode_iei_cell_identifier(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1781 if (bi->bssgp_tree) {
1782 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1783 tf = proto_item_add_subtree(ti, ett_bssgp_cell_identifier);
1785 rai_ci = decode_rai_ci(bi, tf);
1786 proto_item_append_text(ti, ": %s", rai_ci);
1789 bi->offset += ie->value_length;
1795 * 11.3.10 Channel needed
1798 decode_iei_channel_needed(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1799 /* XXX: 'If this IE is used for only one MS, the the first CHANNEL field
1800 is used and the second CHANNEL field is spare.' How know? */
1801 const guint8 MASK_CH1 = 0x03;
1802 const guint8 MASK_CH2 = 0x0c;
1804 guint8 data, ch1, ch2;
1806 if (bi->bssgp_tree) {
1807 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1808 data = tvb_get_guint8(bi->tvb, bi->offset);
1809 ch1 = get_masked_guint8(data, MASK_CH1);
1810 ch2 = get_masked_guint8(data, MASK_CH2);
1811 proto_item_append_text(ti, ": Ch1: %s (%u), Ch2: %s (%u)",
1812 translate_channel_needed(ch1),
1814 translate_channel_needed(ch2),
1817 bi->offset += ie->value_length;
1820 * 11.3.11 DRX Parameters
1823 decode_iei_drx_parameters(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1824 const guint8 MASK_CYCLE_LENGTH_COEFFICIENT = 0xf0;
1825 const guint8 MASK_SPLIT_ON_CCCH = 0x08;
1826 const guint8 MASK_NON_DRX_TIMER = 0x07;
1827 proto_item *ti, *pi;
1830 guint16 cycle_value;
1832 static const value_string tab_non_drx_timer[] = {
1833 { 0, "No non-DRX mode after transfer state" },
1834 { 1, "Max. 1 sec non-DRX mode after transfer state" },
1835 { 2, "Max. 2 sec non-DRX mode after transfer state" },
1836 { 3, "Max. 4 sec non-DRX mode after transfer state" },
1837 { 4, "Max. 8 sec non-DRX mode after transfer state" },
1838 { 5, "Max. 16 sec non-DRX mode after transfer state" },
1839 { 6, "Max. 32 sec non-DRX mode after transfer state" },
1840 { 7, "Max. 64 sec non-DRX mode after transfer state" },
1845 static const value_string tab_cycle_length_coefficient[] = {
1846 { 0, "CN Specific DRX cycle length coefficient not specified by the MS, ie. the system information value 'CN domain specific DRX cycle length' is used" },
1847 { 6, "CN Specific DRX cycle length coefficient 6" },
1848 { 7, "CN Specific DRX cycle length coefficient 7" },
1849 { 8, "CN Specific DRX cycle length coefficient 8" },
1850 { 9, "CN Specific DRX cycle length coefficient 9" },
1852 /* Otherwise "CN Specific DRX cycle length coefficient not specified by the MS" */
1855 if (!bi->bssgp_tree) {
1856 bi->offset += ie->value_length;
1859 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1860 tf = proto_item_add_subtree(ti, ett_bssgp_drx_parameters);
1862 value = tvb_get_guint8(bi->tvb, bi->offset);
1863 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
1864 "SPLIT PG CYCLE: code %u", value);
1865 if ((value >= 1) && (value <= 64)) {
1866 cycle_value = value;
1870 case 0: cycle_value = 704; break;
1871 case 65: cycle_value = 71; break;
1872 case 66: cycle_value = 72; break;
1873 case 67: cycle_value = 74; break;
1874 case 68: cycle_value = 75; break;
1875 case 69: cycle_value = 77; break;
1876 case 70: cycle_value = 79; break;
1877 case 71: cycle_value = 80; break;
1878 case 72: cycle_value = 83; break;
1879 case 73: cycle_value = 86; break;
1880 case 74: cycle_value = 88; break;
1881 case 75: cycle_value = 90; break;
1882 case 76: cycle_value = 92; break;
1883 case 77: cycle_value = 96; break;
1884 case 78: cycle_value = 101; break;
1885 case 79: cycle_value = 103; break;
1886 case 80: cycle_value = 107; break;
1887 case 81: cycle_value = 112; break;
1888 case 82: cycle_value = 116; break;
1889 case 83: cycle_value = 118; break;
1890 case 84: cycle_value = 128; break;
1891 case 85: cycle_value = 141; break;
1892 case 86: cycle_value = 144; break;
1893 case 87: cycle_value = 150; break;
1894 case 88: cycle_value = 160; break;
1895 case 89: cycle_value = 171; break;
1896 case 90: cycle_value = 176; break;
1897 case 91: cycle_value = 192; break;
1898 case 92: cycle_value = 214; break;
1899 case 93: cycle_value = 224; break;
1900 case 94: cycle_value = 235; break;
1901 case 95: cycle_value = 256; break;
1902 case 96: cycle_value = 288; break;
1903 case 97: cycle_value = 320; break;
1904 case 98: cycle_value = 352; break;
1908 proto_item_append_text(ti, " => value %u", cycle_value);
1909 if (cycle_value == 704) {
1910 proto_item_append_text(ti, " (equivalent to no DRX)");
1915 data = tvb_get_guint8(bi->tvb, bi->offset);
1917 value = get_masked_guint8(data, MASK_CYCLE_LENGTH_COEFFICIENT);
1918 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
1919 MASK_CYCLE_LENGTH_COEFFICIENT);
1920 proto_item_append_text(pi, "CN specific DRX cycle length coefficient: %s (%#02x)",
1921 val_to_str(value, tab_cycle_length_coefficient,
1922 "Not specified by the MS"),
1925 value = get_masked_guint8(data, MASK_SPLIT_ON_CCCH);
1926 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_SPLIT_ON_CCCH);
1927 proto_item_append_text(pi, "SPLIT on CCCH: Split pg cycle on CCCH is%s supported by the mobile station",
1928 value == 0 ? " not" : "");
1930 value = get_masked_guint8(data, MASK_NON_DRX_TIMER);
1931 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_NON_DRX_TIMER);
1932 proto_item_append_text(pi, "Non-DRX Timer: %s (%#x)",
1933 val_to_str(value, tab_non_drx_timer, ""), value);
1938 * 11.3.12 eMLPP-Priority
1942 decode_iei_emlpp_priority(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1943 const guint8 MASK_CALL_PRIORITY = 0x07;
1947 static const value_string tab_call_priority[] = {
1948 { 0, "No priority applied" },
1949 { 1, "Call priority level 4" },
1950 { 2, "Call priority level 3" },
1951 { 3, "Call priority level 2" },
1952 { 4, "Call priority level 1" },
1953 { 5, "Call priority level 0" },
1954 { 6, "Call priority level B" },
1955 { 7, "Call priority level A" },
1959 if (bi->bssgp_tree) {
1960 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1961 data = tvb_get_guint8(bi->tvb, bi->offset);
1962 value = get_masked_guint8(data, MASK_CALL_PRIORITY);
1963 proto_item_append_text(ti, ": %s",
1964 val_to_str(value, tab_call_priority, ""));
1966 bi->offset += ie->value_length;
1969 * 11.3.13 Flush Action
1973 decode_iei_flush_action(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1977 static const value_string tab_action_value[] = {
1978 { 0x00, "LLC-PDU(s) deleted" },
1979 { 0x01, "LLC-PDU(s) transferred" },
1981 /* Otherwise "Reserved" */
1984 if (bi->bssgp_tree) {
1985 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1986 value = tvb_get_guint8(bi->tvb, bi->offset);
1987 proto_item_append_text(ti, ": %s (%u)",
1988 val_to_str(value, tab_action_value, "Reserved"),
1992 bi->offset += ie->value_length;
1995 * 11.3.16 LLC Frames Discarded
1999 decode_iei_llc_frames_discarded(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2000 decode_simple_ie(ie, bi, ie_start_offset, "", " frames discarded", TRUE);
2003 * 11.3.17 Location Area
2006 decode_iei_location_area(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2011 if (!bi->bssgp_tree) {
2012 bi->offset += ie->value_length;
2015 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2016 tf = proto_item_add_subtree(ti, ett_bssgp_location_area);
2018 lai = decode_rai(bi, tf);
2019 proto_item_append_text(ti, ": LAI %s", lai);
2023 decode_msrac_additional_access_technologies(proto_tree *tree, tvbuff_t *tvb,
2024 guint64 bo, guint32 length _U_) {
2027 guint8 bl; /* Bit length */
2030 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2031 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2033 proto_item_append_text(pi, "Access Technology Type: %s (%#01x)",
2034 translate_msrac_access_technology_type(value),
2038 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2039 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2041 proto_item_append_text(pi, "GMSK Power Class: Power class %u", value);
2044 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2045 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2047 proto_item_append_text(pi, "8PSK Power Class");
2049 proto_item_append_text(pi, ": 8PSK modulation not supported for uplink");
2052 proto_item_append_text(pi, ": Power Class E%u", value);
2057 struct_bits_exist(guint64 start_bo, guint32 struct_length,
2058 guint64 bo, guint32 num_bits) {
2059 return (bo + num_bits) <= (start_bo + struct_length);
2064 decode_msrac_access_capabilities(proto_tree *tree, tvbuff_t *tvb,
2065 guint64 bo, guint32 struct_length) {
2067 - Struct too short: assume features do not exist
2068 - Struct too long: ignore data and jump to next Access Technology */
2069 proto_item *ti, *pi;
2072 guint8 dgmsc = 0, demsc = 0; /* DTM GPRS/EGPRS Multi Slot Class */
2073 guint8 bl; /* Bit length */
2074 guint64 start_bo = bo;
2076 /* RF Power Capability */
2078 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2079 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2080 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2082 proto_item_append_text(pi, "RF Power Capability");
2084 proto_item_append_text(pi, ": The MS does not support any GSM access technology type");
2087 proto_item_append_text(pi, ": GMSK Power Class %u", value);
2092 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2093 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2097 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2098 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2099 ti = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2100 proto_item_append_text(ti, "A5 Bits: %#02x", value);
2101 tf = proto_item_add_subtree(ti, ett_bssgp_msrac_a5_bits);
2102 for (i = 0; i < bl; i++) {
2103 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo + i, 1);
2104 proto_item_append_text(pi, "Encryption algorithm A5/%u%s available",
2106 value & (0x40 >> i) ? "" : " not");
2111 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2113 proto_item_append_text(pi, "A5 bits: Same as in the immediately preceding Access capabilities field within this IE");
2118 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2119 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2120 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2122 proto_item_append_text(pi, "ESD IND: Controlled Early Classmark Sending"" option is%s implemented",
2123 value == 0 ? " not" : "");
2127 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2128 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2129 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2131 proto_item_append_text(pi, "PS: PS capability%s present",
2132 value == 0 ? " not" : "");
2136 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2137 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2138 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2140 proto_item_append_text(pi, "VBCS:%s VGCS capability %s notifications wanted",
2141 value == 0 ? " No" : "",
2142 value == 0 ? "or no" : "and");
2146 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2147 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2148 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2150 proto_item_append_text(pi, "VBS:%s VBS capability %s notifications wanted",
2151 value == 0 ? " No" : "",
2152 value == 0 ? "or no" : "and");
2154 /* Multislot capability */
2155 /* XXX: 'Error: struct too short, assume features do not exist'
2156 No length is given! */
2158 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2159 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2162 ti = bit_proto_tree_add_text(tree, tvb, bo, bl, "Multislot capability");
2163 tf = proto_item_add_subtree(ti, ett_bssgp_msrac_multislot_capability);
2165 /* HSCSD Multislot Class */
2167 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2168 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2172 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2173 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2174 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2176 proto_item_append_text(pi, "HSCSD Multislot Class");
2177 if ((value > 0 ) && (value < 19)) {
2178 proto_item_append_text(pi, ": Multislot Class %u", value);
2181 proto_item_append_text(pi, ": Reserved");
2186 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo-1, bl);
2187 proto_item_append_text(pi, "HSCSD Multislot Class - Bits are not available" );
2190 /* GPRS Multislot Class, GPRS Extended Dynamic Allocation Capability */
2192 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2193 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2197 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2198 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2199 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2201 proto_item_append_text(pi, "GPRS Multislot Class: Multislot Class %u",
2205 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2206 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2207 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2209 proto_item_append_text(pi, "GPRS Extended Dynamic Allocation Capability: Extended Dynamic Allocation for GPRS is%s implemented",
2210 value == 0 ? " not" : "");
2214 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo-1, bl);
2215 proto_item_append_text(pi, "GPRS Multislot Class: Multislot Class - Bits are not available" );
2218 /* SMS Value, SM Value */
2220 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2221 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2225 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2226 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2227 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2229 proto_item_append_text(pi,
2230 "SMS_VALUE: %u/4 timeslot (~%u microseconds)",
2231 value + 1, (value + 1) * 144);
2234 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2235 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2236 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2238 proto_item_append_text(pi,
2239 "SM_VALUE: %u/4 timeslot (~%u microseconds)",
2240 value + 1, (value + 1) * 144);
2244 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo-1, bl);
2245 proto_item_append_text(pi, "SMS Value, SM Value - Bits are not available" );
2248 /* Additions in release 99 */
2250 /* ECSD Multislot Class */
2252 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2253 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2257 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2258 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2259 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2261 proto_item_append_text(pi, "ECSD Multislot Class");
2262 if ((value > 0 ) && (value < 19)) {
2263 proto_item_append_text(pi, ": Multislot Class %u", value);
2266 proto_item_append_text(pi, ": Reserved");
2271 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo-1, bl);
2272 proto_item_append_text(pi, "ECSD Multislot Class - Bits are not available" );
2275 /* EGPRS Multislot Class, EGPRS Extended Dynamic Allocation Capability */
2277 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2278 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2282 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2283 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2284 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2286 proto_item_append_text(pi, "EGPRS Multislot Class: Multislot Class %u",
2290 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2291 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2292 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2294 proto_item_append_text(pi, "EGPRS Extended Dynamic Allocation Capability: Extended Dynamic Allocation for EGPRS is%s implemented",
2295 value == 0 ? " not" : "");
2299 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo-1, bl);
2300 proto_item_append_text(pi, "EGPRS Multislot Class: Multislot Class - Bits are not available");
2303 /* DTM GPRS Multislot Class */
2305 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2306 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2310 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2311 dgmsc = bssgp_tvb_get_bits8(tvb, bo, bl);
2312 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2314 proto_item_append_text(pi, "DTM GPRS Multislot Class: %s",
2315 translate_msrac_dtm_gprs_multislot_class(dgmsc));
2317 /* Single slot DTM */
2319 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2320 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2321 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2323 proto_item_append_text(pi,
2324 "Single Slot DTM: Single slot DTM%s supported",
2325 value == 0 ? " not" : "");
2327 /* DTM EGPRS Multislot Class */
2329 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2330 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2334 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2335 demsc = bssgp_tvb_get_bits8(tvb, bo, bl);
2336 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2338 proto_item_append_text(pi, "DTM EGPRS Multislot Class: %s",
2339 translate_msrac_dtm_gprs_multislot_class(demsc));
2342 proto_item_set_len(ti, get_num_octets_spanned(start_bo,
2343 (guint32) (bo - start_bo)));
2346 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2348 proto_item_append_text(pi, "Multislot capability: Same as in the immediately preceding Access capabilities field within this IE");
2351 /* Additions in release 99 */
2353 /* 8PSK Power Capability */
2355 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2356 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2360 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2361 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2362 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2364 proto_item_append_text(pi, "8PSK Power Capability");
2367 proto_item_append_text(pi, ": Reserved");
2370 proto_item_append_text(pi, ": Power Class E%u", value);
2372 proto_item_append_text(pi, ", 8PSK modulation capability in uplink");
2375 /* COMPACT Interference Measurement Capability */
2377 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2378 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2379 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2381 proto_item_append_text(pi,
2382 "COMPACT Interference Measurement Capability: %s",
2383 value == 0 ? "Not implemented" : "Implemented");
2385 /* Revision level indicator */
2387 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2388 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2389 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2391 proto_item_append_text(pi, "Revision Level Indicator: The ME is Release '%u %s",
2392 value == 0 ? 98 : 99,
2393 value == 0 ? "or older" : "onwards");
2398 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2399 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2400 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2402 proto_item_append_text(pi, "UMTS FDD Radio Access Technology Capability: UMTS FDD%s supported",
2403 value == 0 ? " not" : "");
2406 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2407 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2408 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2410 proto_item_append_text(pi, "UMTS 3.84 Mcps TDD Radio Access Technology Capability: UMTS 3.84 Mcps TDD%s supported",
2411 value == 0 ? " not" : "");
2414 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2415 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2416 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2418 proto_item_append_text(pi, "CDMA 2000 Radio Access Technology Capability: CDMA 2000%s supported",
2419 value == 0 ? " not" : "");
2422 /* Additions in release 4*/
2424 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2425 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2426 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2428 proto_item_append_text(pi, "UMTS 1.28 Mcps TDD Radio Access Technology Capability: UMTS 1.28 Mcps TDD%s supported",
2429 value == 0 ? " not" : "");
2432 /* GERAN Feature Package 1 */
2434 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2435 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2436 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2438 proto_item_append_text(pi, "GERAN Feature Package 1: GERAN Feature Package 1%s supported",
2439 value == 0 ? " not" : "");
2442 /* Extended DTM xGPRS Multislot Class */
2444 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2445 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2449 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2450 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2451 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2453 proto_item_append_text(pi, "Extended DTM GPRS Multi Slot Class: %s",
2454 translate_msrac_extended_dtm_gprs_multislot_class(value, dgmsc));
2456 /* XXX: 'This field shall be included only if the MS supports EGPRS DTM'.
2459 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2460 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2461 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2463 proto_item_append_text(pi, "Extended DTM EGPRS Multi Slot Class: %s",
2464 translate_msrac_extended_dtm_gprs_multislot_class(value, demsc));
2467 /* Modulation based multislot class support */
2469 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2470 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2471 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2473 proto_item_append_text(pi, "Modulation based multislot class support: %s supported",
2474 value == 0 ? "Not" : "");
2476 /* Additions in release 5 */
2478 /* High multislot capability */
2480 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2481 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2485 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2486 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2487 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2489 proto_item_append_text(pi, "High Multislot Capability: %u", value);
2490 /* XXX: Translate? In that case, which values to compare with?
2491 What if Multislot capability struct was not included? */
2494 /* GERAN Iu Mode Capabilities */
2495 /* XXX: Interpretation? Length? */
2497 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2498 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2499 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2501 proto_item_append_text(pi, "GERAN Iu Mode Capabilities: %s",
2502 value == 0 ? "Not supported" : "Supported");
2504 /* GMSK Multislot Power Profile */
2506 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2507 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2508 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2510 proto_item_append_text(pi, "GMSK Multislot Power Profile: GMSK_MULTI_SLOT_POWER_PROFILE %u",
2513 /* 8PSK Multislot Power Profile */
2514 /* XXX: 'If the MS does not support 8PSK in the uplink, then it shall
2515 set this field to 00' */
2517 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2518 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2519 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2521 proto_item_append_text(pi, "8PSK Multislot Power Profile: 8PSK_MULTI_SLOT_POWER_PROFILE %u",
2524 /* Additions in release 6 */
2526 /* Multiple TBF Capability */
2528 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2529 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2530 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2532 proto_item_append_text(pi, "Multiple TBF Capability: Multiple TBF procedures in A/Gb mode%s supported",
2533 value == 0 ? " not" : "");
2535 /* Downlink Advanced Receiver Performance */
2537 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2538 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2539 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2541 proto_item_append_text(pi, "Downlink Advanced Receiver Performance: Downlink Advanced Receiver Performance %s supported",
2542 value == 0 ? "not" : "- phase 1");
2545 /* Extended RLC_MAC Control Message Segmentation Capability */
2547 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2548 value = bssgp_tvb_get_bits8(tvb, bo, bl);
2549 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2551 proto_item_append_text(pi, "Extended RLC/MAC Control Message Segmentation Capability: Extended RLC/MAC Control Message Segmentation%s supported",
2552 value == 0 ? " not" : "");
2556 decode_msrac_value_part(proto_tree *tree, tvbuff_t *tvb, guint64 bo) {
2557 /* No need to check bi->bssgp_tree here */
2558 const guint8 ADD_ACC_TECHN = 0x0f;
2559 guint8 att, length, bit, bl;
2560 proto_item *ti, *ti2, *pi;
2561 proto_tree *tf, *tf2;
2562 const char *att_name;
2566 ti = bit_proto_tree_add_text(tree, tvb, bo, 8,
2567 "MS RA capability value part");
2568 /* Temporary length of item */
2569 tf = proto_item_add_subtree(ti, ett_bssgp_msrac_value_part);
2572 att = bssgp_tvb_get_bits8(tvb, bo, bl);
2573 att_name = translate_msrac_access_technology_type(att);
2574 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2575 proto_item_append_text(pi, "Access Technology Type: %s (%#01x)", att_name, att);
2576 proto_item_append_text(ti, ": Technology Type %s", att_name);
2580 length = bssgp_tvb_get_bits8(tvb, bo, bl);
2581 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2582 proto_item_append_text(pi, "Length: %u bits", length);
2585 if (att == ADD_ACC_TECHN) {
2586 bo++; /* Always '1' */
2587 ti2 = bit_proto_tree_add_text(tf, tvb, bo, length,
2588 "Additional Access Technologies");
2589 tf2 = proto_item_add_subtree(ti2, ett_bssgp_msrac_additional_access_technologies);
2590 proto_item_set_len(ti, get_num_octets_spanned(start_bo, 4 + 7 + length + 1 + 1));
2591 decode_msrac_additional_access_technologies(tf2, tvb, bo, length);
2593 else if (att <= 0x0b) {
2594 ti2 = bit_proto_tree_add_text(tf, tvb, bo, length, "Access Capabilities");
2595 tf2 = proto_item_add_subtree(ti2, ett_bssgp_msrac_access_capabilities);
2596 proto_item_set_len(ti, get_num_octets_spanned(start_bo, 4 + 7 + length + 1));
2597 decode_msrac_access_capabilities(tf2, tvb, bo, length);
2599 /* else unknown Access Technology Type */
2602 bit = bssgp_tvb_get_bits8(tvb, bo, 1);
2605 decode_msrac_value_part(tree, tvb, bo);
2609 * 11.3.22 MS Radio Access Capability
2612 decode_iei_ms_radio_access_capability(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2616 if (!bi->bssgp_tree) {
2617 bi->offset += ie->value_length;
2620 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2621 tf = proto_item_add_subtree(ti, ett_bssgp_ms_radio_access_capability);
2622 /* Rest of element coded as the value part defined in
2623 * 3GPP TS 24.008, not including 3GPP TS 24.008 IEI and
2624 * 3GPP TS 24.008 octet length indicator.
2625 * 10.5.5.12a MS Radio Access capability
2627 decode_msrac_value_part(tf, bi->tvb, bi->offset * 8);
2628 bi->offset += ie->value_length;
2634 decode_iei_omc_id(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2635 /* XXX: Translation: where in 3GPP TS 12.20? */
2638 if (bi->bssgp_tree) {
2639 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2640 proto_item_append_text(ti, ": %s", BSSGP_NOT_DECODED);
2642 bi->offset += ie->value_length;
2645 * 11.3.24 PDU In Error
2648 decode_iei_pdu_in_error(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2651 if (bi->bssgp_tree) {
2652 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2653 proto_item_append_text(ti, ": Erroneous BSSGP PDU (%u bytes)",
2656 bi->offset += ie->value_length;
2660 decode_iei_priority(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2661 const guint8 MASK_PCI = 0x40;
2662 const guint8 MASK_PRIORITY_LEVEL = 0x3c;
2663 const guint8 MASK_QA = 0x02;
2664 const guint8 MASK_PVI = 0x01;
2665 proto_item *ti, *pi;
2669 static const value_string tab_priority_level[] = {
2671 { 1, "Priority Level 1 = highest priority" },
2672 { 2, "Priority Level 2 = 2nd highest priority" },
2673 { 3, "Priority Level 3 = 3rd highest priority" },
2674 { 4, "Priority Level 4 = 4th highest priority" },
2675 { 5, "Priority Level 5 = 5th highest priority" },
2676 { 6, "Priority Level 6 = 6th highest priority" },
2677 { 7, "Priority Level 7 = 7th highest priority" },
2678 { 8, "Priority Level 8 = 8th highest priority" },
2679 { 9, "Priority Level 9 = 9th highest priority" },
2680 { 10, "Priority Level 10 = 10th highest priority" },
2681 { 11, "Priority Level 11 = 11th highest priority" },
2682 { 12, "Priority Level 12 = 12th highest priority" },
2683 { 13, "Priority Level 13 = 13th highest priority" },
2684 { 14, "Priority Level 14 = lowest priority" },
2685 { 15, "Priority not used" },
2689 if (!bi->bssgp_tree) {
2690 bi->offset += ie->value_length;
2693 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2694 tf = proto_item_add_subtree(ti, ett_bssgp_priority);
2696 data = tvb_get_guint8(bi->tvb, bi->offset);
2698 value = get_masked_guint8(data, MASK_PCI);
2699 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
2701 proto_item_append_text(pi, "PCI: This allocation request %s preempt an existing connection",
2702 value == 0 ? "shall not" : "may");
2704 value = get_masked_guint8(data, MASK_PRIORITY_LEVEL);
2705 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_PRIORITY_LEVEL);
2706 proto_item_append_text(pi, "Priority Level: %s",
2707 val_to_str(value, tab_priority_level, ""));
2709 value = get_masked_guint8(data, MASK_QA);
2710 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_QA);
2711 proto_item_append_text(pi, "QA: Queuing%s allowed",
2712 value == 0 ? " not" : "");
2714 value = get_masked_guint8(data, MASK_PVI);
2715 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_PVI);
2716 proto_item_append_text(pi, "PVI: This connection %s be preempted by another allocation request",
2717 value == 0 ? "shall not" : "might");
2719 bi->offset += ie->value_length;
2722 * 11.3.28 QoS Profile
2725 decode_iei_qos_profile(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2726 const guint8 MASK_CR_BIT = 0x20;
2727 const guint8 MASK_T_BIT = 0x10;
2728 const guint8 MASK_A_BIT = 0x08;
2729 const guint8 MASK_PRECEDENCE = 0x07;
2730 proto_item *ti, *pi;
2733 guint16 peak_bit_rate;
2735 static const value_string tab_precedence_ul[] = {
2736 { 0, "High priority" },
2737 { 1, "Normal priority" },
2738 { 2, "Low priority" },
2742 static const value_string tab_precedence_dl[] = {
2743 { 0, "Radio priority 1" },
2744 { 1, "Radio priority 2" },
2745 { 2, "Radio priority 3" },
2746 { 3, "Radio priority 4" },
2747 { 4, "Radio priority unknown" },
2751 if (!bi->bssgp_tree) {
2752 bi->offset += ie->value_length;
2755 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2756 tf = proto_item_add_subtree(ti, ett_bssgp_qos_profile);
2758 peak_bit_rate = tvb_get_ntohs(bi->tvb, bi->offset);
2759 pi = proto_tree_add_text(tf, bi->tvb, bi->offset, 1, "Peak bit rate: ");
2760 if (peak_bit_rate == 0) {
2761 proto_item_append_text(pi, "Best effort");
2764 proto_item_append_text(pi, "%u bits/s", peak_bit_rate * 100);
2768 data = tvb_get_guint8(bi->tvb, bi->offset);
2770 value = get_masked_guint8(data, MASK_CR_BIT);
2771 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_CR_BIT);
2772 proto_item_append_text(pi, "C/R: The SDU %s command/response frame type",
2773 value == 0 ? "contains" : "does not contain");
2775 value = get_masked_guint8(data, MASK_T_BIT);
2776 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_T_BIT);
2777 proto_item_append_text(pi, "T: The SDU contains %s",
2778 value == 0 ? "signalling (e.g. related to GMM)" : "data");
2780 value = get_masked_guint8(data, MASK_A_BIT);
2781 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_A_BIT);
2782 proto_item_append_text(pi, "A: Radio interface uses RLC/MAC %s functionality",
2783 value == 0 ? "ARQ " : "UNITDATA ");
2785 value = get_masked_guint8(data, MASK_PRECEDENCE);
2786 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_PRECEDENCE);
2787 proto_item_append_text(pi, "Precedence: ");
2790 proto_item_append_text(pi, "%s", val_to_str(value, tab_precedence_ul,
2791 "Reserved (Low priority)"));
2794 proto_item_append_text(pi, "%s", val_to_str(value, tab_precedence_dl,
2795 "Reserved (Radio priority 3)"));
2797 proto_item_append_text(pi, " (%#x)", value);
2801 * 11.3.29 Radio Cause
2804 decode_iei_radio_cause(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2808 static const value_string tab_radio_cause[] = {
2809 { 0x00, "Radio contact lost with the MS" },
2810 { 0x01, "Radio link quality insufficient to continue communication" },
2811 { 0x02, "Cell reselection ordered" },
2812 { 0x03, "Cell reselection prepare" },
2813 { 0x04, "Cell reselection failure" },
2815 /* Otherwise "Reserved (Radio contact lost with the MS)" */
2818 if (bi->bssgp_tree) {
2819 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2820 value = tvb_get_guint8(bi->tvb, bi->offset);
2821 proto_item_append_text(ti, ": %s (%#02x)",
2822 val_to_str(value, tab_radio_cause, "Reserved (Radio contact lost with the MS)"),
2825 bi->offset += ie->value_length;
2829 decode_iei_ra_cap_upd_cause(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2833 static const value_string tab_cause_value[] = {
2834 { 0x00, "OK, RA capability IE present" },
2835 { 0x01, "TLLI unknown in SGSN" },
2836 { 0x02, "No RA capabilities or IMSI available for this MS" },
2838 /* Otherwise "Reserved (TLLI unknown in SGSN)" */
2841 if (bi->bssgp_tree) {
2842 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2843 value = tvb_get_guint8(bi->tvb, bi->offset);
2844 proto_item_append_text(ti, ": %s (%#2x)",
2845 val_to_str(value, tab_cause_value, "Reserved (TLLI unknown in SGSN)"),
2848 bi->offset += ie->value_length;
2852 decode_iei_routing_area(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2857 if (!bi->bssgp_tree) {
2858 bi->offset += ie->value_length;
2861 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2862 tf = proto_item_add_subtree(ti, ett_bssgp_routing_area);
2864 rai = decode_rai(bi, tf);
2865 proto_item_append_text(ti, ": RAI %s", rai);
2869 decode_iei_tlli(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2874 tlli = tvb_get_ntohl(bi->tvb, bi->offset);
2876 if (bi->bssgp_tree) {
2877 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2878 proto_item_append_text(ti, ": %#04x", tlli);
2879 /* By Stefan Boman LN/Ericsson 2006-07-14 --
2880 * Commented the following four lines. Preventing redundant data
2883 ti = bssgp_proto_tree_add_ie(ie, bi, bi->offset);
2885 /* If we want to keep the posibillity to filter on ie:s without a Tag and the ie "content"
2886 * this is how it has to be done.
2888 tf = proto_item_add_subtree(ti, ett_bssgp_tlli);
2890 proto_tree_add_item(tf, hf_bssgp_tlli,
2891 bi->tvb, bi->offset, 4, BSSGP_LITTLE_ENDIAN);
2896 if (check_col(bi->pinfo->cinfo, COL_INFO)) {
2897 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP,
2901 if (check_col(bi->pinfo->cinfo, COL_BSSGP_TLLI)) {
2902 col_add_fstr(bi->pinfo->cinfo, COL_BSSGP_TLLI, "%#04x", tlli);
2905 decode_nri(bi->bssgp_tree, bi, tlli);
2909 decode_iei_tmsi(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2914 tmsi = tvb_get_ntohl(bi->tvb, bi->offset);
2916 if (bi->bssgp_tree) {
2917 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2918 proto_item_append_text(ti, ": %#04x", tmsi);
2920 ti = bssgp_proto_tree_add_ie(ie, bi, bi->offset);
2921 tf = proto_item_add_subtree(ti, ett_bssgp_tmsi_ptmsi);
2923 proto_tree_add_item(tf, hf_bssgp_tmsi_ptmsi,
2924 bi->tvb, bi->offset, 4, BSSGP_LITTLE_ENDIAN);
2928 if (check_col(bi->pinfo->cinfo, COL_INFO)) {
2929 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP,
2930 "(P)TMSI %#4x", tmsi);
2932 decode_nri(bi->bssgp_tree, bi, tmsi);
2936 decode_iei_trigger_id(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2937 /* XXX: value is 20 octets long! How add/show? */
2940 if (bi->bssgp_tree) {
2941 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2943 bi->offset += ie->value_length;
2947 proto_tree_add_lsa_id(build_info_t *bi, proto_tree *tree) {
2948 guint32 data, lsa_id;
2951 data = tvb_get_ntoh24(bi->tvb, bi->offset);
2954 pi = proto_tree_add_text(tree, bi->tvb, bi->offset, 3,
2955 "LSA ID: %#03x (%s)", lsa_id,
2957 "Universal LSA" : "PLMN significant number");
2962 decode_iei_lsa_identifier_list(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2963 const guint8 MASK_EP = 0x01;
2964 proto_item *ti, *pi;
2969 if (!bi->bssgp_tree) {
2970 bi->offset += ie->value_length;
2973 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2974 tf = proto_item_add_subtree(ti, ett_bssgp_lsa_identifier_list);
2976 value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_EP);
2977 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_EP);
2978 proto_item_append_text(pi, "EP: The escape PLMN is%s broadcast",
2979 value == 0 ? " not" : "");
2982 num_lsa_ids = (ie->value_length - 1) / 3;
2984 for (i = 0; i < num_lsa_ids; i++) {
2985 proto_tree_add_lsa_id(bi, tf);
2990 decode_iei_lsa_information(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2991 const guint8 MASK_LSA_ONLY = 0x01;
2992 const guint8 MASK_ACT = 0x20;
2993 const guint8 MASK_PREF = 0x10;
2994 const guint8 MASK_PRIORITY = 0x0f;
2995 proto_item *ti, *ti2, *pi;
2996 proto_tree *tf, *tf2;
2997 int num_lsa_infos, i;
3000 static const value_string tab_priority[] = {
3001 { 0, "Priority 1 = lowest priority" },
3002 { 1, "Priority 2 = 2nd lowest priority" },
3003 { 2, "Priority 3 = 3rd lowest priority" },
3004 { 3, "Priority 4 = 4th lowest priority" },
3005 { 4, "Priority 5 = 5th lowest priority" },
3006 { 5, "Priority 6 = 6th lowest priority" },
3007 { 6, "Priority 7 = 7th lowest priority" },
3008 { 7, "Priority 8 = 8th lowest priority" },
3009 { 8, "Priority 9 = 9th lowest priority" },
3010 { 9, "Priority 10 = 10th lowest priority" },
3011 { 10, "Priority 11 = 11th lowest priority" },
3012 { 11, "Priority 12 = 12th lowest priority" },
3013 { 12, "Priority 13 = 13th lowest priority" },
3014 { 13, "Priority 14 = 14th lowest priority" },
3015 { 14, "Priority 15 = 15th lowest priority" },
3016 { 15, "Priority 16 = highest priority" },
3020 if (!bi->bssgp_tree) {
3021 bi->offset += ie->value_length;
3024 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3025 tf = proto_item_add_subtree(ti, ett_bssgp_lsa_information);
3027 value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_LSA_ONLY);
3028 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_LSA_ONLY);
3029 proto_item_append_text(pi, "LSA Only: %s",
3031 "The subscriber has only access to the LSAs that are defined by the LSA information element" :
3032 "Allow an emergency call");
3035 num_lsa_infos = (ie->value_length - 1) / 4;
3037 for (i = 0; i < num_lsa_infos; i++) {
3038 ti2 = proto_tree_add_text(tf, bi->tvb, bi->offset, 4,
3039 "LSA Identification and attributes %u", i + 1);
3040 tf2 = proto_item_add_subtree(ti2, ett_bssgp_lsa_information_lsa_identification_and_attributes);
3042 data = tvb_get_guint8(bi->tvb, bi->offset);
3044 value = get_masked_guint8(data, MASK_ACT);
3045 pi = proto_tree_add_bitfield8(tf2, bi->tvb, bi->offset, MASK_ACT);
3046 proto_item_append_text(pi, "Act: The subscriber %s active mode support in the LSA",
3047 value == 0 ? "does not have" : "has");
3049 value = get_masked_guint8(data, MASK_PREF);
3050 pi = proto_tree_add_bitfield8(tf2, bi->tvb, bi->offset, MASK_PREF);
3051 proto_item_append_text(pi, "Pref: The subscriber %s preferential access in the LSA",
3052 value == 0 ? "does not have" : "has");
3054 value = get_masked_guint8(data, MASK_PRIORITY);
3055 pi = proto_tree_add_bitfield8(tf2, bi->tvb, bi->offset, MASK_PRIORITY);
3056 proto_item_append_text(pi, "Priority: %s",
3057 val_to_str(value, tab_priority, ""));
3060 proto_tree_add_lsa_id(bi, tf2);
3065 decode_iei_gprs_timer(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3066 const guint8 MASK_UNIT_VALUE = 0xe0;
3067 const guint8 MASK_TIMER_VALUE = 0x1f;
3071 static const value_string tab_unit_value[] = {
3072 { 0, "incremented in multiples of 2 s" },
3073 { 1, "incremented in multiples of 1 minute" },
3074 { 2, "incremented in multiples of decihours" },
3075 { 3, "incremented in multiples of 500 msec" },
3076 { 7, "the timer does not expire" },
3078 /* Otherwise "incremented in multiples of 1 minute" */
3081 if (bi->bssgp_tree) {
3082 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3083 data = tvb_get_guint8(bi->tvb, bi->offset);
3084 value = get_masked_guint8(data, MASK_TIMER_VALUE);
3085 proto_item_append_text(ti, ": %u", value);
3087 value = get_masked_guint8(data, MASK_UNIT_VALUE);
3088 proto_item_append_text(ti, ", %s",
3089 val_to_str(value, tab_unit_value,
3090 "incremented in multiples of 1 minute"));
3092 bi->offset += ie->value_length;
3096 decode_iei_abqp(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3097 const guint8 MASK_DELAY_CLASS = 0x38;
3098 const guint8 MASK_RELIABILITY_CLASS = 0x07;
3099 const guint8 MASK_PEAK_THROUGHPUT = 0xf0;
3100 const guint8 MASK_PRECEDENCE_CLASS = 0x07;
3101 const guint8 MASK_MEAN_THROUGHPUT = 0x1f;
3102 const guint8 MASK_TRAFFIC_CLASS = 0xe0;
3103 const guint8 MASK_DELIVERY_ORDER = 0x18;
3104 const guint8 MASK_DELIVERY_OF_ERRONEOUS_SDU = 0x07;
3105 const guint8 MASK_RESIDUAL_BER = 0xf0;
3106 const guint8 MASK_SDU_ERROR_RATIO = 0x0f;
3107 const guint8 MASK_TRANSFER_DELAY = 0xfc;
3108 const guint8 MASK_TRAFFIC_HANDLING_PRIORITY = 0x03;
3109 const guint8 MASK_SIGNALLING_INDICATION = 0x10;
3110 const guint8 MASK_SOURCE_STATISTICS_DESCRIPTOR = 0x0f;
3111 const guint8 TRAFFIC_CLASS_CONVERSATIONAL = 1;
3112 const guint8 TRAFFIC_CLASS_STREAMING = 2;
3113 const guint8 TRAFFIC_CLASS_INTERACTIVE = 3;
3114 const guint8 TRAFFIC_CLASS_BACKGROUND = 4;
3115 guint8 data, value, traffic_class;
3116 proto_item *ti, *pi;
3119 if (!bi->bssgp_tree) {
3120 bi->offset += ie->value_length;
3123 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3124 tf = proto_item_add_subtree(ti, ett_bssgp_abqp);
3126 data = tvb_get_guint8(bi->tvb, bi->offset);
3128 value = get_masked_guint8(data, MASK_DELAY_CLASS);
3129 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_DELAY_CLASS);
3130 proto_item_append_text(pi, "Delay Class: %s (%#x)",
3131 translate_abqp_delay_class(value, bi), value);
3133 value = get_masked_guint8(data, MASK_RELIABILITY_CLASS);
3134 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3135 MASK_RELIABILITY_CLASS);
3136 proto_item_append_text(pi, "Reliability Class: %s (%#x)",
3137 translate_abqp_reliability_class(value, bi), value);
3140 data = tvb_get_guint8(bi->tvb, bi->offset);
3142 value = get_masked_guint8(data, MASK_PEAK_THROUGHPUT);
3143 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3144 MASK_PEAK_THROUGHPUT);
3145 proto_item_append_text(pi, "Peak Throughput: %s (%#x)",
3146 translate_abqp_peak_throughput(value, bi), value);
3148 value = get_masked_guint8(data, MASK_PRECEDENCE_CLASS);
3149 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3150 MASK_PRECEDENCE_CLASS);
3151 proto_item_append_text(pi, "Precedence Class: %s (%#x)",
3152 translate_abqp_precedence_class(value, bi), value);
3155 data = tvb_get_guint8(bi->tvb, bi->offset);
3157 value = get_masked_guint8(data, MASK_MEAN_THROUGHPUT);
3158 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3159 MASK_MEAN_THROUGHPUT);
3160 proto_item_append_text(pi, "Mean Throughput: %s (%#02x)",
3161 translate_abqp_mean_throughput(value, bi), value);
3163 * A QoS IE received without octets 6-16, without octets 14-16, or without octets 15-16 shall be accepted by the
3167 if (ie->value_length == 3)
3170 data = tvb_get_guint8(bi->tvb, bi->offset);
3172 traffic_class = get_masked_guint8(data, MASK_TRAFFIC_CLASS);
3173 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_TRAFFIC_CLASS);
3174 proto_item_append_text(pi, "Traffic Class: %s (%#x)",
3175 translate_abqp_traffic_class(traffic_class, bi),
3177 if ((traffic_class == TRAFFIC_CLASS_INTERACTIVE) ||
3178 (traffic_class == TRAFFIC_CLASS_BACKGROUND)) {
3179 proto_item_append_text(pi, " (ignored)");
3182 value = get_masked_guint8(data, MASK_DELIVERY_ORDER);
3183 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_DELIVERY_ORDER);
3184 proto_item_append_text(pi, "Delivery Order: %s (%#x)",
3185 translate_abqp_delivery_order(value, bi), value);
3187 value = get_masked_guint8(data, MASK_DELIVERY_OF_ERRONEOUS_SDU);
3188 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3189 MASK_DELIVERY_OF_ERRONEOUS_SDU);
3190 proto_item_append_text(pi, "Delivery of Erroneous SDU: %s (%#x)",
3191 translate_abqp_delivery_of_erroneous_sdu(value, bi),
3196 value = tvb_get_guint8(bi->tvb, bi->offset);
3197 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
3198 "Maximum SDU Size: %s",
3199 translate_abqp_max_sdu_size(value, bi));
3203 value = tvb_get_guint8(bi->tvb, bi->offset);
3204 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
3205 "Maximum bit rate for uplink: %s",
3206 translate_abqp_max_bit_rate_for_ul(value, bi));
3210 value = tvb_get_guint8(bi->tvb, bi->offset);
3211 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
3212 "Maximum bit rate for downlink: %s",
3213 translate_abqp_max_bit_rate_for_dl(value, bi));
3216 data = tvb_get_guint8(bi->tvb, bi->offset);
3218 value = get_masked_guint8(data, MASK_RESIDUAL_BER);
3219 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_RESIDUAL_BER);
3220 proto_item_append_text(pi, "Residual BER: %s (%#x)",
3221 translate_abqp_residual_ber(value, bi), value);
3223 value = get_masked_guint8(data, MASK_SDU_ERROR_RATIO);
3224 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3225 MASK_SDU_ERROR_RATIO);
3226 proto_item_append_text(pi, "SDU Error Ratio: %s (%#x)",
3227 translate_abqp_sdu_error_ratio(value, bi), value);
3230 data = tvb_get_guint8(bi->tvb, bi->offset);
3232 value = get_masked_guint8(data, MASK_TRANSFER_DELAY);
3233 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_TRANSFER_DELAY);
3234 proto_item_append_text(pi, "Transfer Delay: %s (%#02x)",
3235 translate_abqp_transfer_delay(value, bi), value);
3237 value = get_masked_guint8(data, MASK_TRAFFIC_HANDLING_PRIORITY);
3238 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3239 MASK_TRAFFIC_HANDLING_PRIORITY);
3240 proto_item_append_text(pi, "Traffic Handling Priority: %s (%#x)",
3241 translate_abqp_traffic_handling_priority(value, bi),
3243 if ((traffic_class == TRAFFIC_CLASS_CONVERSATIONAL) ||
3244 (traffic_class == TRAFFIC_CLASS_STREAMING) ||
3245 (traffic_class == TRAFFIC_CLASS_BACKGROUND)) {
3246 proto_item_append_text(pi, " (ignored)");
3251 value = tvb_get_guint8(bi->tvb, bi->offset);
3252 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
3253 "Guaranteed bit rate for uplink: %s",
3254 translate_abqp_guaranteed_bit_rate_for_ul(value, bi));
3258 value = tvb_get_guint8(bi->tvb, bi->offset);
3259 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
3260 "Guaranteed bit rate for downlink: %s",
3261 translate_abqp_guaranteed_bit_rate_for_dl(value, bi));
3263 * A QoS IE received without octets 6-16, without octets 14-16, or without octets 15-16 shall be accepted by the
3268 if (ie->value_length == 11)
3271 data = tvb_get_guint8(bi->tvb, bi->offset);
3273 value = get_masked_guint8(data, MASK_SIGNALLING_INDICATION);
3274 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3275 MASK_SIGNALLING_INDICATION);
3276 proto_item_append_text(pi, "Signalling Indication: %s for signalling traffic",
3277 value == 0 ? "Not optimized" : "Optimized");
3278 if ((traffic_class == TRAFFIC_CLASS_CONVERSATIONAL) ||
3279 (traffic_class == TRAFFIC_CLASS_STREAMING) ||
3280 (traffic_class == TRAFFIC_CLASS_BACKGROUND)) {
3281 proto_item_append_text(pi, " (ignored)");
3284 value = get_masked_guint8(data, MASK_SOURCE_STATISTICS_DESCRIPTOR);
3285 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3286 MASK_SOURCE_STATISTICS_DESCRIPTOR);
3287 proto_item_append_text(pi, "Source Statistics Descriptor: %s (%#x)",
3288 translate_abqp_source_statistics_descriptor(value, bi),
3290 if ((traffic_class == TRAFFIC_CLASS_INTERACTIVE) ||
3291 (traffic_class == TRAFFIC_CLASS_BACKGROUND)) {
3292 proto_item_append_text(pi, " (ignored)");
3295 * A QoS IE received without octets 6-16, without octets 14-16, or without octets 15-16 shall be accepted by the
3300 if (ie->value_length == 12)
3303 value = tvb_get_guint8(bi->tvb, bi->offset);
3304 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
3305 "Maximum bit rate for downlink (extended): %s",
3306 translate_abqp_max_bit_rate_for_dl_extended(value, bi));
3310 value = tvb_get_guint8(bi->tvb, bi->offset);
3311 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
3312 "Guaranteed bit rate for downlink (extended): %s",
3313 translate_abqp_guaranteed_bit_rate_for_dl_extended(value, bi));
3318 decode_iei_feature_bitmap(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3319 const guint8 MASK_ENHANCED_RADIO_STATUS = 0x40;
3320 const guint8 MASK_PFC_FC = 0x20;
3321 const guint8 MASK_RIM = 0x10;
3322 const guint8 MASK_LCS = 0x08;
3323 const guint8 MASK_INR = 0x04;
3324 const guint8 MASK_CBL = 0x02;
3325 const guint8 MASK_PFC = 0x01;
3326 proto_item *ti, *pi;
3330 if (!bi->bssgp_tree) {
3331 bi->offset += ie->value_length;
3334 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3335 tf = proto_item_add_subtree(ti, ett_bssgp_feature_bitmap);
3337 data = tvb_get_guint8(bi->tvb, bi->offset);
3339 value = get_masked_guint8(data, MASK_ENHANCED_RADIO_STATUS);
3340 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3341 MASK_ENHANCED_RADIO_STATUS);
3342 proto_item_append_text(pi, "Enhanced Radio Status: Enhanced Radio Status Procedures%s supported",
3343 value == 0 ? " not" : "");
3345 value = get_masked_guint8(data, MASK_PFC_FC);
3346 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_PFC_FC);
3347 proto_item_append_text(pi, "PFC_FC: PFC Flow Control Procedures%s supported",
3348 value == 0 ? " not" : "");
3350 value = get_masked_guint8(data, MASK_RIM);
3351 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_RIM);
3352 proto_item_append_text(pi, "RIM: RAN Information Management (RIM) Procedures%s supported",
3353 value == 0 ? " not" : "");
3355 value = get_masked_guint8(data, MASK_LCS);
3356 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_LCS);
3357 proto_item_append_text(pi, "LCS: LCS Procedures%s supported",
3358 value == 0 ? " not" : "");
3360 value = get_masked_guint8(data, MASK_INR);
3361 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_INR);
3362 proto_item_append_text(pi, "INR: Inter-NSE re-routing%s supported",
3363 value == 0 ? " not" : "");
3365 value = get_masked_guint8(data, MASK_CBL);
3366 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_CBL);
3367 proto_item_append_text(pi, "CBL: Current Bucket Level Procedures%s supported",
3368 value == 0 ? " not" : "");
3370 value = get_masked_guint8(data, MASK_PFC);
3371 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_PFC);
3372 proto_item_append_text(pi, "PFC: Packet Flow Context Procedures%s supported",
3373 value == 0 ? " not" : "");
3375 bi->offset += ie->value_length;
3379 decode_iei_bucket_full_ratio(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3382 if (bi->bssgp_tree) {
3383 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3384 bssgp_pi_append_bucket_full_ratio(ti, bi->tvb, bi->offset);
3386 bi->offset += ie->value_length;
3390 decode_iei_service_utran_cco(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3391 const guint8 MASK_SERVICE_UTRAN_CCO = 0x07;
3395 static const value_string tab_service_utran_cco[] = {
3396 { 0, "Network initiated cell change order procedure to UTRAN should be performed" },
3397 { 1, "Network initiated cell change order procedure to UTRAN should not be performed" },
3398 { 2, "Network initiated cell change order procedure to UTRAN shall not be performed" },
3400 /* Otherwise "No information available" */
3403 if (bi->bssgp_tree) {
3404 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3405 data = tvb_get_guint8(bi->tvb, bi->offset);
3406 value = get_masked_guint8(data, MASK_SERVICE_UTRAN_CCO);
3407 proto_item_append_text(ti, ": %s (%#02x)",
3408 val_to_str(value, tab_service_utran_cco,
3409 "No information available"),
3412 bi->offset += ie->value_length;
3416 decode_iei_nsei(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3417 proto_item *ti, *hidden_item;
3420 nsei = tvb_get_ntohs(bi->tvb, bi->offset);
3422 if (bi->bssgp_tree) {
3423 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3424 proto_item_append_text(ti, ": %u", nsei);
3425 hidden_item = proto_tree_add_item(bi->bssgp_tree, hf_bssgp_nsei,
3426 bi->tvb, bi->offset, 2, BSSGP_LITTLE_ENDIAN);
3427 PROTO_ITEM_SET_HIDDEN(hidden_item);
3429 bi->offset += ie->value_length;
3431 if (check_col(bi->pinfo->cinfo, COL_INFO)) {
3432 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP,
3438 decode_iei_lcs_qos(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3439 const guint8 MASK_VERT = 0x01;
3440 const guint8 MASK_XA = 0x80;
3441 const guint8 MASK_ACCURACY = 0x7f;
3442 const guint8 MASK_RT = 0xc0;
3443 proto_item *ti, *pi;
3445 guint8 data, value, vert;
3447 static const value_string tab_rt[] = {
3448 { 0, "Response time is not specified" },
3450 { 2, "Delay tolerant" },
3455 if (!bi->bssgp_tree) {
3456 bi->offset += ie->value_length;
3459 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3460 tf = proto_item_add_subtree(ti, ett_bssgp_lcs_qos);
3462 data = tvb_get_guint8(bi->tvb, bi->offset);
3463 vert = get_masked_guint8(data, MASK_VERT);
3464 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_VERT);
3465 proto_item_append_text(pi, "VERT: Vertical coordinate is%s requested",
3466 vert == 0 ? " not" : "");
3469 data = tvb_get_guint8(bi->tvb, bi->offset);
3471 value = get_masked_guint8(data, MASK_XA);
3472 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_XA);
3473 proto_item_append_text(pi, "HA: Horizontal Accuracy is%s specified",
3474 value == 0 ? " not" : "");
3477 value = get_masked_guint8(data, MASK_ACCURACY);
3478 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_ACCURACY);
3479 proto_item_append_text(pi, "Horizontal Accuracy: %.1f m",
3480 10 * (pow(1.1, (double)value) - 1));
3484 data = tvb_get_guint8(bi->tvb, bi->offset);
3487 value = get_masked_guint8(data, MASK_XA);
3488 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_XA);
3489 proto_item_append_text(pi, "VA: Vertical Accuracy is%s specified",
3490 value == 0 ? " not" : "");
3492 value = get_masked_guint8(data, MASK_ACCURACY);
3493 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_ACCURACY);
3494 proto_item_append_text(pi, "Vertical Accuracy: %.1f m",
3495 45 * (pow(1.025, (double)value) - 1));
3499 data = tvb_get_guint8(bi->tvb, bi->offset);
3500 value = get_masked_guint8(data, MASK_RT);
3502 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_RT);
3503 proto_item_append_text(pi, "RT: %s",
3504 val_to_str(value, tab_rt, ""));
3509 decode_iei_lcs_client_type(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3510 const guint8 MASK_CATEGORY = 0xf0;
3511 const guint8 MASK_SUBTYPE = 0x0f;
3512 proto_item *ti, *pi;
3514 guint8 data, category, subtype;
3516 static const value_string tab_category[] = {
3517 { 0, "Value Added Client" },
3518 /* { 1, ??? XXX }, */
3519 { 2, "PLMN Operator" },
3520 { 3, "Emergency Services" },
3521 { 4, "Lawful Intercept Services" },
3523 /* Otherwise "Reserved" */
3526 if (!bi->bssgp_tree) {
3527 bi->offset += ie->value_length;
3530 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3531 tf = proto_item_add_subtree(ti, ett_bssgp_lcs_client_type);
3533 data = tvb_get_guint8(bi->tvb, bi->offset);
3535 category = get_masked_guint8(data, MASK_CATEGORY);
3536 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_CATEGORY);
3537 proto_item_append_text(pi, "Category: %s (%#x)",
3538 val_to_str(category, tab_category, "Reserved"),
3541 subtype = get_masked_guint8(data, MASK_SUBTYPE);
3542 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_SUBTYPE);
3543 proto_item_append_text(pi, "Subtype: ");
3548 proto_item_append_text(pi, "Unspecified"); break;
3551 proto_item_append_text(pi, "Reserved"); break;
3553 /* case 1: ??? XXX*/
3556 case 0: proto_item_append_text(pi, "Unspecified"); break;
3557 case 1: proto_item_append_text(pi, "Broadcast service"); break;
3558 case 2: proto_item_append_text(pi, "O&M"); break;
3559 case 3: proto_item_append_text(pi, "Anonymous statistics"); break;
3560 case 4: proto_item_append_text(pi, "Target MS service support node"); break;
3561 default: proto_item_append_text(pi, "Reserved"); break;
3567 proto_item_append_text(pi, "Unspecified"); break;
3570 proto_item_append_text(pi, "Reserved"); break;
3572 default: /* Not category == 1! */
3573 proto_item_append_text(pi, "Reserved"); break;
3580 decode_iei_requested_gps_assistance_data(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3581 const guint8 MASK_A = 0x01;
3582 const guint8 MASK_B = 0x02;
3583 const guint8 MASK_C = 0x04;
3584 const guint8 MASK_D = 0x08;
3585 const guint8 MASK_E = 0x10;
3586 const guint8 MASK_F = 0x20;
3587 const guint8 MASK_G = 0x40;
3588 const guint8 MASK_H = 0x80;
3589 const guint8 MASK_I = 0x01;
3590 const guint8 MASK_NSAT = 0xf0;
3591 const guint8 MASK_T_TOE_LIMIT = 0x0f;
3592 const guint8 MASK_SAT_ID =0x3f;
3593 proto_tree *tf, *tf2;
3594 proto_item *ti, *ti2, *pi;
3595 guint8 data, value, d, nsat;
3599 if (!bi->bssgp_tree) {
3600 bi->offset += ie->value_length;
3603 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3604 tf = proto_item_add_subtree(ti, ett_bssgp_requested_gps_assistance_data);
3606 data = tvb_get_guint8(bi->tvb, bi->offset);
3608 value = get_masked_guint8(data, MASK_A);
3609 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_A);
3610 proto_item_append_text(pi, "A: Almanac is%s srequested",
3611 value == 0 ? " not" : "");
3613 value = get_masked_guint8(data, MASK_B);
3614 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_B);
3615 proto_item_append_text(pi, "B: UTC Model is%s requested",
3616 value == 0 ? " not" : "");
3618 value = get_masked_guint8(data, MASK_C);
3619 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_C);
3620 proto_item_append_text(pi, "C: Ionospheric Model is%s requested",
3621 value == 0 ? " not" : "");
3623 value = get_masked_guint8(data, MASK_D);
3624 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_D);
3625 proto_item_append_text(pi, "D: Navigation Model is%s requested",
3626 value == 0 ? " not" : "");
3629 value = get_masked_guint8(data, MASK_E);
3630 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_E);
3631 proto_item_append_text(pi, "E: DGPS Corrections are%s requested",
3632 value == 0 ? " not" : "");
3634 value = get_masked_guint8(data, MASK_F);
3635 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_F);
3636 proto_item_append_text(pi, "F: Reference Location is%s requested",
3637 value == 0 ? " not" : "");
3639 value = get_masked_guint8(data, MASK_G);
3640 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_G);
3641 proto_item_append_text(pi, "G: Reference Time is%s requested",
3642 value == 0 ? " not" : "");
3644 value = get_masked_guint8(data, MASK_H);
3645 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_H);
3646 proto_item_append_text(pi, "H: Acquisition Assistance is%s requested",
3647 value == 0 ? " not" : "");
3651 value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_I);
3652 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_I);
3653 proto_item_append_text(pi, "I: Real-Time Integrity is%s requested",
3654 value == 0 ? " not" : "");
3657 data = tvb_get_guint8(bi->tvb, bi->offset);
3658 gps_week = (data & 0xc0) << 2;
3659 data = tvb_get_guint8(bi->tvb, bi->offset + 1);
3661 proto_tree_add_text(tf, bi->tvb, bi->offset, 2,
3662 "GPS Week: %u", gps_week);
3665 value = tvb_get_guint8(bi->tvb, bi->offset);
3666 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
3667 "GPS Toe: %u", value);
3670 data = tvb_get_guint8(bi->tvb, bi->offset);
3671 nsat = get_masked_guint8(data, MASK_NSAT);
3672 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_NSAT);
3673 proto_item_append_text(pi, "NSAT: %u", value);
3675 value = get_masked_guint8(data, MASK_T_TOE_LIMIT);
3676 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_T_TOE_LIMIT);
3677 proto_item_append_text(pi, "T-Toe Limit: %u", value);
3680 for (i = 0; i < nsat; i++) {
3681 ti2 = proto_tree_add_text(tf, bi->tvb, bi->offset, 2, "Satellite %u", i);
3682 tf2 = proto_item_add_subtree(ti2, ett_bssgp_requested_gps_assistance_data_satellite);
3684 value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_SAT_ID);
3685 pi = proto_tree_add_bitfield8(tf2, bi->tvb, bi->offset, MASK_SAT_ID);
3686 proto_item_append_text(pi, "SatId: %u", value);
3687 proto_item_append_text(ti2, ": Id %u", value);
3690 value = tvb_get_guint8(bi->tvb, bi->offset);
3691 proto_tree_add_text(tf2, bi->tvb, bi->offset, 1,
3693 proto_item_append_text(ti2, ", IODE %u", value);
3699 decode_iei_location_type(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3700 const guint8 LOCATION_ASSISTANCE = 1;
3701 const guint8 DECIPHERING_KEYS = 2;
3706 static const value_string tab_location_information[] = {
3707 { 0, "Current geographic location" },
3708 { 1, "Location assistance information for the target MS" },
3709 { 2, "Deciphering keys for broadcast assistance data for the target MS" },
3711 /* Otherwise "Reserved" */
3714 static const value_string tab_positioning_method[] = {
3716 { 1, "Mobile Assisted E-OTD" },
3717 { 2, "Mobile Based E-OTD" },
3718 { 3, "Assisted GPS" },
3720 /* Otherwise "Reserved" */
3723 if (!bi->bssgp_tree) {
3724 bi->offset += ie->value_length;
3727 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3728 tf = proto_item_add_subtree(ti, ett_bssgp_location_type);
3730 value = tvb_get_guint8(bi->tvb, bi->offset);
3731 proto_tree_add_text(tf, bi->tvb, bi->offset, 1, "Location Information: %s",
3732 val_to_str(value, tab_location_information,
3736 if ((value == LOCATION_ASSISTANCE) || (value == DECIPHERING_KEYS)) {
3737 value = tvb_get_guint8(bi->tvb, bi->offset);
3738 proto_tree_add_text(tf, bi->tvb, bi->offset, 1, "Positioning Method: %s",
3739 val_to_str(value, tab_positioning_method,
3746 decode_iei_location_estimate(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3747 /* XXX: Which paragraph in 3GPP TS 23.032?*/
3750 if (bi->bssgp_tree) {
3751 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3752 proto_item_append_text(ti, ": %s", BSSGP_NOT_DECODED);
3754 if (ie->value_length != BSSGP_UNKNOWN) {
3755 bi->offset += ie->value_length;
3760 decode_iei_positioning_data(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3761 const guint8 MASK_PDD = 0x0f;
3762 const guint8 MASK_METHOD = 0xf8;
3763 const guint8 MASK_USAGE = 0x07;
3764 proto_item *ti, *pi;
3766 guint8 data, value, i, num_methods;
3768 if (!bi->bssgp_tree) {
3769 bi->offset += ie->value_length;
3772 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3773 tf = proto_item_add_subtree(ti, ett_bssgp_positioning_data);
3775 value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_PDD);
3776 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_PDD);
3777 proto_item_append_text(pi, "Positioning Data Discriminator: %s",
3779 "Indicate usage of each positioning method that was attempted either successfully or unsuccessfully" :
3783 num_methods = ie->value_length - 1;
3784 for (i = 0; i < num_methods; i++) {
3785 data = tvb_get_guint8(bi->tvb, bi->offset);
3787 value = get_masked_guint8(data, MASK_METHOD);
3788 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_METHOD);
3789 proto_item_append_text(pi, "Method: ");
3792 case 0: proto_item_set_text(pi, "Timing Advance"); break;
3793 case 1: proto_item_set_text(pi, "Reserved"); break;
3794 case 2: proto_item_set_text(pi, "Reserved"); break;
3795 case 3: proto_item_set_text(pi, "Mobile Assisted E-OTD"); break;
3796 case 4: proto_item_set_text(pi, "Mobile Based E-OTD"); break;
3797 case 5: proto_item_set_text(pi, "Mobile Assisted GPS"); break;
3798 case 6: proto_item_set_text(pi, "Mobile Based GPS"); break;
3799 case 7: proto_item_set_text(pi, "Conventional GPS"); break;
3800 case 8: proto_item_set_text(pi, "U-TDOA"); break;
3802 if ((value >= 9) && (value <= 0x0f)) {
3803 proto_item_set_text(pi, "Reserved for GSM");
3806 proto_item_set_text(pi, "Reserved for network specific positioning methods");
3809 proto_item_append_text(pi, " (%#02x)", value); /* Method */
3811 value = get_masked_guint8(data, MASK_USAGE);
3814 case 0: proto_item_append_text(pi, " attempted unsuccessfully due to failure or interruption "); break;
3815 case 1: proto_item_append_text(pi, " attempted successfully: results not used to generate location"); break;
3816 case 2: proto_item_append_text(pi, " attempted successfully: results used to verify but not generate location"); break;
3817 case 3: proto_item_append_text(pi, " attempted successfully: results used to generate location"); break;
3818 case 4: proto_item_append_text(pi, " attempted successfully: case where MS supports multiple mobile based"
3819 " positioning methods and the actual method or methods used by the MS cannot be determined"); break;
3820 default: ; /* ??? */
3822 proto_item_append_text(pi, " (%#x)", value); /* Usage */
3828 decode_iei_deciphering_keys(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3829 const guint8 MASK_KEY_FLAG = 0x01;
3830 proto_item *ti, *pi;
3834 if (!bi->bssgp_tree) {
3835 bi->offset += ie->value_length;
3839 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3840 tf = proto_item_add_subtree(ti, ett_bssgp_deciphering_keys);
3842 data = tvb_get_guint8(bi->tvb, bi->offset);
3843 value = get_masked_guint8(data, MASK_KEY_FLAG);
3844 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_KEY_FLAG);
3845 proto_item_append_text(pi, "Ciphering Key Flag: %u", value);
3848 proto_tree_add_text(tf, bi->tvb, bi->offset, 7,
3849 "Current Deciphering Key Value");
3852 proto_tree_add_text(tf, bi->tvb, bi->offset, 7,
3853 "Next Deciphering Key Value");
3858 decode_iei_lcs_priority(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3859 /* XXX: coding (3GPP TS 29.002 7.6.11.7)? */
3862 if (bi->bssgp_tree) {
3863 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3864 proto_item_append_text(ti, ": %s", BSSGP_NOT_DECODED);
3866 bi->offset += ie->value_length;
3870 decode_iei_lcs_cause(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3875 static const value_string tab_cause_value[] = {
3876 { 0, "Unspecified" },
3877 { 1, "System failure" },
3878 { 2, "Protocol error" },
3879 { 3, "Data missing in position request" },
3880 { 4, "Unexpected value in position request" },
3881 { 5, "Position method failure" },
3882 { 6, "Target MS unreachable" },
3883 { 7, "Location request aborted" },
3884 { 8, "Facility not supported" },
3885 { 9, "Inter-BSC handover ongoing" },
3886 { 10, "Intra-BSC handover ongoing" },
3887 { 11, "Congestion" },
3888 { 12, "Inter NSE cell change" },
3889 { 13, "Routing area update" },
3890 { 14, "PTMSI reallocation" },
3891 { 15, "Suspension of GPRS services" },
3893 /* Otherwise "Unspecified" */
3896 static const value_string tab_diagnostic_value[] = {
3897 { 0, "Congestion" },
3898 { 1, "Insufficient resources" },
3899 { 2, "Insufficient measurement data" },
3900 { 3, "Inconsistent measurement data" },
3901 { 4, "Location procedure not completed" },
3902 { 5, "Location procedure not supported by target MS" },
3903 { 6, "QoS not attainable" },
3904 { 7, "Position method not available in network" },
3905 { 8, "Position method not available in location area" },
3907 /* Otherwise "Unrecognized => ignored" */
3910 if (!bi->bssgp_tree) {
3911 bi->offset += ie->value_length;
3914 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3915 value = tvb_get_guint8(bi->tvb, bi->offset);
3917 if (ie->value_length == 1) {
3918 /* Diagnostic value not included */
3919 proto_item_append_text(ti, ": %s (%#02x)",
3920 val_to_str(value, tab_cause_value, "Unspecified"),
3926 tf = proto_item_add_subtree(ti, ett_bssgp_lcs_cause);
3928 proto_tree_add_text(tf, bi->tvb, bi->offset, 1, ": %s (%#02x)",
3929 val_to_str(value, tab_cause_value, "Unspecified"),
3933 value = tvb_get_guint8(bi->tvb, bi->offset);
3934 proto_tree_add_text(tf, bi->tvb, bi->offset, 1, ": %s (%#02x)",
3935 val_to_str(value, tab_diagnostic_value,
3936 "Unrecognized => ignored"),
3942 decode_iei_lcs_capability(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3943 const guint8 MASK_OTD_A = 0x10;
3944 const guint8 MASK_OTD_B = 0x08;
3945 const guint8 MASK_GPS_A = 0x04;
3946 const guint8 MASK_GPS_B = 0x02;
3947 const guint8 MASK_GPS_C = 0x01;
3948 proto_item *ti, *pi;
3952 if (!bi->bssgp_tree) {
3953 bi->offset += ie->value_length;
3956 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3957 tf = proto_item_add_subtree(ti, ett_bssgp_lcs_capability);
3959 data = tvb_get_guint8(bi->tvb, bi->offset);
3961 value = get_masked_guint8(data, MASK_OTD_A);
3962 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_OTD_A);
3963 proto_item_append_text(pi, "OTD-A: MS Assisted E-OTD%s supported",
3964 value == 0 ? " not" : "");
3966 value = get_masked_guint8(data, MASK_OTD_B);
3967 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_OTD_B);
3968 proto_item_append_text(pi, "OTD-B: MS Based E-OTD%s supported",
3969 value == 0 ? " not" : "");
3971 value = get_masked_guint8(data, MASK_GPS_A);
3972 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_GPS_A);
3973 proto_item_append_text(pi, "GPS-A: MS Assisted GPS%s supported",
3974 value == 0 ? " not" : "");
3976 value = get_masked_guint8(data, MASK_GPS_B);
3977 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_GPS_B);
3978 proto_item_append_text(pi, "GPS-B: MS Based GPS%s supported",
3979 value == 0 ? " not" : "");
3981 value = get_masked_guint8(data, MASK_GPS_C);
3982 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_GPS_C);
3983 proto_item_append_text(pi, "GPS-C: Conventional GPS%s supported",
3984 value == 0 ? " not" : "");
3990 decode_iei_rrlp_flags(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3991 const guint8 MASK_FLAG1 = 0x01;
3995 if (bi->bssgp_tree) {
3996 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3997 value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_FLAG1);
3998 proto_item_append_text(ti, ": Flag1:%s Position Command (BSS to SGSN) or final response (SGSN to BSS) (%u)",
3999 value == 0 ? " Not a" : "", value);
4004 static void /* [7] 11.3.61 RIM Application Identity */
4005 decode_iei_rim_application_identity(bssgp_ie_t *ie _U_, build_info_t *bi, int ie_start_offset _U_) {
4009 if (!bi->bssgp_tree) {
4014 ti = proto_tree_add_item(bi->bssgp_tree, hf_bssgp_appid,
4015 bi->tvb, bi->offset, 1, FALSE);
4017 appid = tvb_get_guint8(bi->tvb, bi->offset);
4019 case 0: proto_item_append_text(ti, " - Reserved"); break;
4020 case 1: proto_item_append_text(ti, " - Network Assisted Cell Change (NACC)"); break;
4021 case 0x10: proto_item_append_text(ti, " - System Information 3 (SI3)"); break;
4022 case 0x11: proto_item_append_text(ti, " - MBMS data channel"); break;
4023 default: proto_item_append_text(ti, " - Reserved");
4031 decode_ran_information_common(build_info_t *bi, proto_tree *parent_tree) {
4035 guint8 num_rai_cis, i;
4037 ti = proto_tree_add_text(parent_tree, bi->tvb, bi->offset, 8,
4038 "RAI + CI for Source Cell");
4039 tf = proto_item_add_subtree(ti, ett_bssgp_rai_ci);
4041 rai_ci = decode_rai_ci(bi, tf);
4042 proto_item_append_text(ti, ": %s", rai_ci);
4044 num_rai_cis = tvb_get_guint8(bi->tvb, bi->offset);
4045 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
4046 "%u ""RAI+CI for Destination Cell"" follow%s",
4047 num_rai_cis, (num_rai_cis == 0) ? "" : "s");
4050 for (i = 0; i < num_rai_cis; i++) {
4051 ti = proto_tree_add_text(parent_tree, bi->tvb, bi->offset, 8,
4052 """RAI + CI for Destination Cell"" (%u)", i + 1);
4053 tf = proto_item_add_subtree(ti, ett_bssgp_rai_ci);
4054 rai_ci = decode_rai_ci(bi, tf);
4055 proto_item_append_text(ti, ": %s", rai_ci);
4061 * 11.3.77 RIM Routing Information
4063 static const value_string ra_discriminator_vals[] = {
4064 { 0, "A Cell Identifier is used to identify a GERAN cell" },
4065 { 1, "A Global RNC-ID is used to identify a UTRAN RNC" },
4070 decode_iei_rim_routing_information(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
4075 if (bi->bssgp_tree) {
4076 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
4077 tf = proto_item_add_subtree(ti, ett_bssgp_rim_routing_information);
4079 proto_tree_add_item(tf, hf_bssgp_ra_discriminator,
4080 bi->tvb, bi->offset, 1, FALSE);
4082 data = tvb_get_guint8(bi->tvb, bi->offset);
4088 proto_tree_add_item(tf, hf_bssgp_ci,
4089 bi->tvb, bi->offset, 2, BSSGP_LITTLE_ENDIAN);
4093 bi->offset += ie->value_length;
4098 static void /* [7] 11.62a.1 */
4099 decode_iei_ran_container_unit(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
4103 if (!bi->bssgp_tree) {
4108 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
4109 tf = proto_item_add_subtree(ti, ett_bssgp_ran_information_request_container_unit);
4113 decode_iei_application_error(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
4117 if (bi->bssgp_tree) {
4118 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
4119 tf = proto_item_add_subtree(ti, ett_bssgp_ran_information_container_unit);
4121 proto_tree_add_item(tf, hf_bssgp_iei_nacc_cause, bi->tvb, bi->offset, 1, FALSE);
4122 proto_tree_add_text(tf, bi->tvb, bi->offset, tvb_length(bi->tvb) - bi->offset , "Erroneous Application Container including IEI and LI");
4125 bi->offset += ie->value_length;
4130 * 11.3.63.1.1 RAN-INFORMATION-REQUEST Application Container for the NACC Application
4133 decode_iei_ran_information_request_application_container(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
4138 if (bi->bssgp_tree) {
4139 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
4140 tf = proto_item_add_subtree(ti, ett_bssgp_ran_information_container_unit);
4143 * Octet 3-10 Reporting Cell Identifier:
4144 * This field is encoded as the Cell Identifier defined in sub-clause 11.3.9
4146 rai_ci = decode_rai_ci(bi, tf);
4147 proto_item_append_text(ti, ": %s", rai_ci);
4150 bi->offset += ie->value_length;
4154 decode_iei_ran_information_application_container(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
4155 const guint8 MASK_NUMBER_OF_SI_PSI = 0xfe;
4156 const guint8 MASK_UNIT_TYPE = 0x01;
4157 const guint8 TYPE_SI = 0;
4158 const guint8 TYPE_PSI = 1;
4159 const guint8 LEN_SI = 21;
4160 const guint8 LEN_PSI = 22;
4161 proto_item *ti, *pi;
4163 guint8 num_si_psi, type_si_psi, data, i;
4165 if (! bi->bssgp_tree) {
4169 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
4170 tf = proto_item_add_subtree(ti, ett_bssgp_ran_information_container_unit);
4172 /* don't work, ran_information_common read number of rai's but it is only one.
4173 decode_ran_information_common(bi, tf); */
4174 decode_rai_ci(bi,tf);
4176 data = tvb_get_guint8(bi->tvb, bi->offset);
4177 num_si_psi = get_masked_guint8(data, MASK_NUMBER_OF_SI_PSI);
4178 type_si_psi = get_masked_guint8(data, MASK_UNIT_TYPE);
4180 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
4181 MASK_NUMBER_OF_SI_PSI);
4182 proto_item_append_text(pi, "Number of SI/PSI: %u ""SI/PSI"" follow%s",
4184 num_si_psi < 2 ? "s" : "");
4186 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_UNIT_TYPE);
4187 proto_item_append_text(pi, "Type: %s messages as specified for %s follow",
4188 type_si_psi == TYPE_SI ? "SI" : "PSI",
4189 type_si_psi == TYPE_SI ? "BCCH" : "PBCCH");
4193 for (i = 0; i < num_si_psi; i++) {
4194 if (type_si_psi == TYPE_SI) {
4195 proto_tree_add_text(tf, bi->tvb, bi->offset, LEN_SI,
4196 " SI (%u), %u octets", i + 1, LEN_SI);
4197 /* XXX: Not decoded yet; which section in 3GPP TS 44.018? */
4198 proto_tree_add_item(tf, hf_bssgp_rrc_si_msg_type, bi->tvb, bi->offset, 1, FALSE);
4200 * Add decoding in packet-gsm_a.c ? Needs a new exported function "gsm_a_decode_rr_message?)
4203 bi->offset += LEN_SI;
4205 else if (type_si_psi == TYPE_PSI) {
4206 proto_tree_add_text(tf, bi->tvb, bi->offset, LEN_PSI,
4207 " PSI (%u), %u octets", i + 1, LEN_PSI);
4208 /* XXX: Not decoded yet; which section in 3GPP TS 44.060?
4210 System information messages: Reference
4211 Packet System Information Type 1 11.2.18
4212 Packet System Information Type 2 11.2.19
4213 Packet System Information Type 3 11.2.20
4214 Packet System Information Type 3 bis 11.2.21
4215 Packet System Information Type 3 ter 11.2.21a
4216 Packet System Information Type 3 quater 11.2.21b
4217 Packet System Information Type 5 11.2.23
4218 Packet System Information Type 6 11.2.23a
4219 Packet System Information Type 7 11.2.23b
4220 Packet System Information Type 8 11.2.24
4221 Packet System Information Type 13 11.2.25
4222 Packet System Information Type 14 11.2.25a
4223 Packet System Information Type 15 11.2.25b
4224 Packet System Information Type 16 11.2.25c
4226 bi->offset += LEN_PSI;
4230 static const value_string ran_inf_req_pdu_type_ext_vals[] = {
4231 { 0,"RAN-INFORMATION-REQUEST/Stop PDU" },
4232 { 1,"RAN-INFORMATION-REQUEST/Single Report PDU" },
4233 { 2,"RAN-INFORMATION-REQUEST/Multiple Report PDU" },
4242 static const value_string ran_inf_pdu_type_ext_vals[] = {
4243 { 0,"RAN-INFORMATION/Stop PDU" },
4244 { 1,"RAN-INFORMATION/Single Report PDU" },
4245 { 2,"RAN-INFORMATION/Initial Multiple Report PDU" },
4246 { 3,"RAN-INFORMATION/Multiple Report PDU" },
4247 { 4,"RAN-INFORMATION/End PDU" },
4253 /* 11.3.65 RIM PDU Indications 3GPP TS 48.018 version 6.7.0 Release 6 */
4255 decode_iei_rim_pdu_indications(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
4256 /** const guint8 MASK_EXT = 0x0E; **/
4257 const guint8 MASK_ACK = 0x01;
4258 proto_item *ti, *pi;
4262 if (!bi->bssgp_tree) {
4263 bi->offset += ie->value_length;
4266 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
4267 tf = proto_item_add_subtree(ti, ett_bssgp_rim_pdu_indications);
4269 data = tvb_get_guint8(bi->tvb, bi->offset);
4271 if (bi->pdutype == BSSGP_IEI_RAN_INFORMATION_CONTAINER_UNIT) {
4272 proto_tree_add_item(tf, hf_ran_inf_pdu_type_ext, bi->tvb, bi->offset, 1, FALSE);
4274 proto_tree_add_item(tf, hf_ran_inf_req_pdu_type_ext, bi->tvb, bi->offset, 1, FALSE);
4277 value = get_masked_guint8(data, MASK_ACK);
4278 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_ACK);
4279 proto_item_append_text(pi, "ACK: %sACK requested",
4280 value == 0 ? "No " : "");
4285 decode_iei_number_of_container_units(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
4289 if (!bi->bssgp_tree) {
4290 bi->offset += ie->value_length;
4293 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
4294 value = tvb_get_guint8(bi->tvb, bi->offset);
4295 proto_item_append_text(ti, ": %u Container Unit%s follow%s",
4297 value == 0 ? "" : "s",
4298 value > 0 ? "s" : "");
4303 decode_iei_pfc_flow_control_parameters(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
4304 proto_tree *tf, *tf2;
4305 proto_item *ti, *ti2, *pi;
4306 guint8 num_pfc, i, pfc_len;
4307 gboolean b_pfc_included;
4309 if (!bi->bssgp_tree) {
4310 bi->offset += ie->value_length;
4313 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
4314 tf = proto_item_add_subtree(ti, ett_bssgp_pfc_flow_control_parameters);
4316 num_pfc = tvb_get_guint8(bi->tvb, bi->offset);
4317 pi = proto_tree_add_text(bi->bssgp_tree, bi->tvb, bi->offset, 1,
4318 "Number of PFCs: ");
4321 proto_item_append_text(pi, "%u", num_pfc);
4324 proto_item_append_text(pi, "Reserved");
4328 if (num_pfc == 0) return;
4330 pfc_len = (ie->value_length - 1) / num_pfc;
4331 b_pfc_included = (pfc_len == 6);
4333 for (i = 0; i < num_pfc; i++) {
4334 ti2 = proto_tree_add_text(tf, bi->tvb, bi->offset, pfc_len,
4336 tf2 = proto_item_add_subtree(ti2, ett_bssgp_pfc_flow_control_parameters_pfc);
4338 pi = proto_tree_add_text(tf2, bi->tvb, bi->offset, 1, "PFI");
4339 bssgp_pi_append_pfi(pi, bi->tvb, bi->offset);
4342 pi = proto_tree_add_text(tf2, bi->tvb, bi->offset, 2, "BMax_PFC");
4343 bssgp_pi_append_bucket_size(pi, bi->tvb, bi->offset);
4346 pi = proto_tree_add_text(tf2, bi->tvb, bi->offset, 2, "R_PFC");
4347 bssgp_pi_append_bucket_leak_rate(pi, bi->tvb, bi->offset);
4350 if (b_pfc_included) {
4351 pi = proto_tree_add_text(tf2, bi->tvb, bi->offset, 1, "B_PFC");
4352 bssgp_pi_append_bucket_full_ratio(pi, bi->tvb, bi->offset);
4359 decode_iei_global_cn_id(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
4365 if (!bi->bssgp_tree) {
4366 bi->offset += ie->value_length;
4369 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
4370 tf = proto_item_add_subtree(ti, ett_bssgp_global_cn_id);
4372 mcc_mnc = decode_mcc_mnc(bi, tf);
4373 proto_item_append_text(ti, ": PLMN-Id %s", mcc_mnc);
4375 value = tvb_get_ntohs(bi->tvb, bi->offset);
4376 proto_tree_add_text(tf, bi->tvb, bi->offset, 2,
4377 "CN-ID: %u", value);
4378 proto_item_append_text(ti, ", CN-Id %u", value);
4383 decode_ie(bssgp_ie_t *ie, build_info_t *bi) {
4384 int org_offset = bi->offset;
4386 if (tvb_length_remaining(bi->tvb, bi->offset) < 1) {
4387 /* TODO This code does not work well with omitted Optional elements
4388 proto_tree_add_none_format(bi->bssgp_tree, NULL, bi->tvb, 0, -1, "[tvb_length_remaining] length remaining: %d", tvb_length_remaining(bi->tvb, bi->offset));
4392 switch (ie->format) {
4393 case BSSGP_IE_FORMAT_TLV:
4394 if (!check_correct_iei(ie, bi)) {
4396 /* TODO This code does not work well with omitted Optional elements */
4397 proto_tree_add_none_format(bi->bssgp_tree, NULL, bi->tvb, 0, -1, "[BSSGP_IE_FORMAT_TLV] format: %d", ie->format);
4401 bi->offset++; /* Account for type */
4402 ie->total_length = 1;
4403 get_value_length(ie, bi);
4405 case BSSGP_IE_FORMAT_TV:
4406 if (!check_correct_iei(ie, bi)) {
4408 /* TODO This code does not work well with omitted Optional elements */
4409 proto_tree_add_none_format(bi->bssgp_tree, NULL, bi->tvb, 0, -1, "[BSSGP_IE_FORMAT_TV] format: %d", ie->format);
4413 bi->offset++; /* Account for type */
4414 ie->value_length = ie->total_length - 1;
4416 case BSSGP_IE_FORMAT_V:
4417 ie->value_length = ie->total_length;
4424 case BSSGP_IEI_ALIGNMENT_OCTETS:
4425 decode_iei_alignment_octets(ie, bi, org_offset);
4427 case BSSGP_IEI_BMAX_DEFAULT_MS:
4428 decode_bucket_size(ie, bi, org_offset);
4430 case BSSGP_IEI_BSS_AREA_INDICATION:
4431 /* XXX: 'The recipient shall ignore the value of this octet'??? */
4432 decode_simple_ie(ie, bi, org_offset, "BSS Indicator", "", TRUE);
4434 case BSSGP_IEI_BUCKET_LEAK_RATE:
4435 decode_bucket_leak_rate(ie, bi, org_offset);
4437 case BSSGP_IEI_BVCI:
4438 decode_iei_bvci(ie, bi, org_offset);
4440 case BSSGP_IEI_BVC_BUCKET_SIZE:
4441 decode_bucket_size(ie, bi, org_offset);
4443 case BSSGP_IEI_BVC_MEASUREMENT:
4444 decode_queuing_delay(ie, bi, org_offset);
4446 case BSSGP_IEI_CAUSE:
4447 decode_iei_cause(ie, bi, org_offset);
4449 case BSSGP_IEI_CELL_IDENTIFIER:
4450 decode_iei_cell_identifier(ie, bi, org_offset);
4452 case BSSGP_IEI_CHANNEL_NEEDED:
4453 decode_iei_channel_needed(ie, bi, org_offset);
4455 case BSSGP_IEI_DRX_PARAMETERS:
4456 decode_iei_drx_parameters(ie, bi, org_offset);
4458 case BSSGP_IEI_EMLPP_PRIORITY:
4459 decode_iei_emlpp_priority(ie, bi, org_offset);
4461 case BSSGP_IEI_FLUSH_ACTION:
4462 decode_iei_flush_action(ie, bi, org_offset);
4464 case BSSGP_IEI_IMSI:
4465 decode_mobile_identity(ie, bi, org_offset);
4467 case BSSGP_IEI_LLC_PDU:
4468 bssgp_proto_handoff(ie, bi, org_offset, llc_handle);
4470 case BSSGP_IEI_LLC_FRAMES_DISCARDED:
4471 decode_iei_llc_frames_discarded(ie, bi, org_offset);
4473 case BSSGP_IEI_LOCATION_AREA:
4474 decode_iei_location_area(ie, bi, org_offset);
4476 case BSSGP_IEI_MOBILE_ID:
4477 decode_mobile_identity(ie, bi, org_offset);
4479 case BSSGP_IEI_MS_BUCKET_SIZE:
4480 decode_bucket_size(ie, bi, org_offset);
4482 case BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY:
4483 decode_iei_ms_radio_access_capability(ie, bi, org_offset);
4485 case BSSGP_IEI_OMC_ID:
4486 decode_iei_omc_id(ie, bi, org_offset);
4488 case BSSGP_IEI_PDU_IN_ERROR:
4489 decode_iei_pdu_in_error(ie, bi, org_offset);
4491 case BSSGP_IEI_PDU_LIFETIME:
4492 decode_queuing_delay(ie, bi, org_offset);
4494 case BSSGP_IEI_PRIORITY:
4495 decode_iei_priority(ie, bi, org_offset);
4497 case BSSGP_IEI_QOS_PROFILE:
4498 decode_iei_qos_profile(ie, bi, org_offset);
4500 case BSSGP_IEI_RADIO_CAUSE:
4501 decode_iei_radio_cause(ie, bi, org_offset);
4503 case BSSGP_IEI_RA_CAP_UPD_CAUSE:
4504 decode_iei_ra_cap_upd_cause(ie, bi, org_offset);
4506 case BSSGP_IEI_ROUTING_AREA:
4507 decode_iei_routing_area(ie, bi, org_offset);
4509 case BSSGP_IEI_R_DEFAULT_MS:
4510 decode_bucket_leak_rate(ie, bi, org_offset);
4512 case BSSGP_IEI_SUSPEND_REFERENCE_NUMBER:
4513 decode_simple_ie(ie, bi, org_offset, "", "", TRUE);
4516 decode_simple_ie(ie, bi, org_offset, "", "", TRUE);
4518 case BSSGP_IEI_TLLI:
4519 decode_iei_tlli(ie, bi, org_offset);
4521 case BSSGP_IEI_TMSI:
4522 decode_iei_tmsi(ie, bi, org_offset);
4524 case BSSGP_IEI_TRACE_REFERENCE:
4525 decode_simple_ie(ie, bi, org_offset, "", "", TRUE);
4527 case BSSGP_IEI_TRACE_TYPE:
4528 /* XXX: Coding unknown (Specification withdrawn) 3GPP TS 32.008 */
4529 decode_simple_ie(ie, bi, org_offset, "", "", TRUE);
4531 case BSSGP_IEI_TRANSACTION_ID:
4532 decode_simple_ie(ie, bi, org_offset, "", "", TRUE);
4534 case BSSGP_IEI_TRIGGER_ID:
4535 decode_iei_trigger_id(ie, bi, org_offset);
4537 case BSSGP_IEI_NUMBER_OF_OCTETS_AFFECTED:
4538 decode_simple_ie(ie, bi, org_offset, "", "", TRUE);
4540 case BSSGP_IEI_LSA_IDENTIFIER_LIST:
4541 decode_iei_lsa_identifier_list(ie, bi, org_offset);
4543 case BSSGP_IEI_LSA_INFORMATION:
4544 decode_iei_lsa_information(ie, bi, org_offset);
4547 decode_pfi(ie, bi, org_offset);
4549 case BSSGP_IEI_GPRS_TIMER:
4550 decode_iei_gprs_timer(ie, bi, org_offset);
4552 case BSSGP_IEI_ABQP:
4553 decode_iei_abqp(ie, bi, org_offset);
4555 case BSSGP_IEI_FEATURE_BITMAP:
4556 decode_iei_feature_bitmap(ie, bi, org_offset);
4558 case BSSGP_IEI_BUCKET_FULL_RATIO:
4559 decode_iei_bucket_full_ratio(ie, bi, org_offset);
4561 case BSSGP_IEI_SERVICE_UTRAN_CCO:
4562 decode_iei_service_utran_cco(ie, bi, org_offset);
4564 case BSSGP_IEI_NSEI:
4565 decode_iei_nsei(ie, bi, org_offset);
4567 case BSSGP_IEI_RRLP_APDU:
4568 bssgp_proto_handoff(ie, bi, org_offset, rrlp_handle);
4570 case BSSGP_IEI_LCS_QOS:
4571 decode_iei_lcs_qos(ie, bi, org_offset);
4573 case BSSGP_IEI_LCS_CLIENT_TYPE:
4574 decode_iei_lcs_client_type(ie, bi, org_offset);
4576 case BSSGP_IEI_REQUESTED_GPS_ASSISTANCE_DATA:
4577 decode_iei_requested_gps_assistance_data(ie, bi, org_offset);
4579 case BSSGP_IEI_LOCATION_TYPE:
4580 decode_iei_location_type(ie, bi, org_offset);
4582 case BSSGP_IEI_LOCATION_ESTIMATE:
4583 decode_iei_location_estimate(ie, bi, org_offset);
4585 case BSSGP_IEI_POSITIONING_DATA:
4586 decode_iei_positioning_data(ie, bi, org_offset);
4588 case BSSGP_IEI_DECIPHERING_KEYS:
4589 decode_iei_deciphering_keys(ie, bi, org_offset);
4591 case BSSGP_IEI_LCS_PRIORITY:
4592 decode_iei_lcs_priority(ie, bi, org_offset);
4594 case BSSGP_IEI_LCS_CAUSE:
4595 decode_iei_lcs_cause(ie, bi, org_offset);
4597 case BSSGP_IEI_LCS_CAPABILITY:
4598 decode_iei_lcs_capability(ie, bi, org_offset);
4600 case BSSGP_IEI_RRLP_FLAGS:
4601 decode_iei_rrlp_flags(ie, bi, org_offset);
4603 case BSSGP_IEI_RIM_ROUTING_INFORMATION:
4604 decode_iei_rim_routing_information(ie, bi, org_offset);
4606 case BSSGP_IEI_RIM_APPLICATION_IDENTITY:
4607 decode_iei_rim_application_identity(ie, bi, org_offset);
4609 case BSSGP_IEI_RIM_SEQUENCE_NUMBER:
4610 decode_simple_ie(ie, bi, org_offset, "", "", TRUE);
4612 case BSSGP_IEI_RIM_PROTOCOL_VERSION:
4613 decode_simple_ie(ie, bi, org_offset, "", "", TRUE);
4616 case BSSGP_IEI_RAN_INFORMATION_REQUEST_APPLICATION_CONTAINER:
4617 decode_iei_ran_information_request_application_container(ie, bi, org_offset);
4619 case BSSGP_IEI_RAN_INFORMATION_APPLICATION_CONTAINER:
4620 decode_iei_ran_information_application_container(ie, bi, org_offset);
4623 case BSSGP_IEI_RAN_INFORMATION_REQUEST_CONTAINER_UNIT:
4624 decode_iei_ran_container_unit(ie, bi, org_offset);
4626 case BSSGP_IEI_RAN_INFORMATION_CONTAINER_UNIT:
4627 decode_iei_ran_container_unit(ie, bi, org_offset);
4629 case BSSGP_IEI_RAN_INFORMATION_APPLICATION_ERROR_CONTAINER_UNIT:
4630 decode_iei_ran_container_unit(ie, bi, org_offset);
4632 case BSSGP_IEI_RAN_INFORMATION_ACK_RIM_CONTAINER:
4633 decode_iei_ran_container_unit(ie, bi, org_offset);
4635 case BSSGP_IEI_RAN_INFORMATION_ERROR_RIM_CONTAINER:
4636 decode_iei_ran_container_unit(ie, bi, org_offset);
4639 case BSSGP_IEI_APPLICATION_ERROR_CONTAINER:
4640 decode_iei_application_error(ie, bi, org_offset);
4644 case BSSGP_IEI_RIM_PDU_INDICATIONS:
4645 decode_iei_rim_pdu_indications(ie, bi, org_offset);
4647 case BSSGP_IEI_NUMBER_OF_CONTAINER_UNITS:
4648 decode_iei_number_of_container_units(ie, bi, org_offset);
4650 case BSSGP_IEI_PFC_FLOW_CONTROL_PARAMETERS:
4651 decode_iei_pfc_flow_control_parameters(ie, bi, org_offset);
4653 case BSSGP_IEI_GLOBAL_CN_ID:
4654 decode_iei_global_cn_id(ie, bi, org_offset);
4662 decode_pdu_general(bssgp_ie_t *ies, int num_ies, build_info_t *bi) {
4664 for (i = 0; i < num_ies; i++) {
4665 decode_ie(&ies[i], bi);
4670 decode_pdu_dl_unitdata(build_info_t *bi) {
4671 bssgp_ie_t ies[] = {
4672 { BSSGP_IEI_TLLI, "TLLI (current)",
4673 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_V, BSSGP_UNKNOWN, 4 },
4675 { BSSGP_IEI_QOS_PROFILE, NULL,
4676 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_V, BSSGP_UNKNOWN, 3 },
4678 { BSSGP_IEI_PDU_LIFETIME, NULL,
4679 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4},
4681 { BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY, NULL,
4682 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN},
4684 { BSSGP_IEI_PRIORITY, NULL,
4685 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3},
4687 { BSSGP_IEI_DRX_PARAMETERS, NULL,
4688 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4},
4690 { BSSGP_IEI_IMSI, NULL,
4691 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN},
4693 { BSSGP_IEI_TLLI, "TLLI (old)",
4694 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6},
4696 { BSSGP_IEI_PFI, NULL,
4697 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3},
4699 { BSSGP_IEI_LSA_INFORMATION, NULL,
4700 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN},
4702 { BSSGP_IEI_SERVICE_UTRAN_CCO, NULL,
4703 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3},
4705 { BSSGP_IEI_ALIGNMENT_OCTETS, NULL,
4706 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN},
4708 { BSSGP_IEI_LLC_PDU, NULL,
4709 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN},
4712 bi->ul_data = FALSE;
4714 decode_pdu_general(ies, 13, bi);
4718 decode_pdu_ul_unitdata(build_info_t *bi) {
4719 bssgp_ie_t ies[] = {
4720 { BSSGP_IEI_TLLI, NULL,
4721 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_V, BSSGP_UNKNOWN, 4 },
4723 { BSSGP_IEI_QOS_PROFILE, NULL,
4724 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_V, BSSGP_UNKNOWN, 3 },
4726 { BSSGP_IEI_CELL_IDENTIFIER, NULL,
4727 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
4729 { BSSGP_IEI_PFI, NULL,
4730 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4732 { BSSGP_IEI_LSA_IDENTIFIER_LIST, NULL,
4733 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
4735 { BSSGP_IEI_ALIGNMENT_OCTETS, NULL,
4736 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
4738 { BSSGP_IEI_LLC_PDU, NULL,
4739 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
4741 bi->dl_data = FALSE;
4744 decode_pdu_general(ies, 7, bi);
4748 decode_pdu_ra_capability(build_info_t *bi) {
4749 bssgp_ie_t ies[] = {
4750 { BSSGP_IEI_TLLI, NULL,
4751 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4753 { BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY, NULL,
4754 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN},
4757 bi->ul_data = FALSE;
4759 decode_pdu_general(ies, 2, bi);
4763 decode_pdu_ptm_unitdata(build_info_t *bi) {
4764 proto_tree_add_text(bi->bssgp_tree, bi->tvb, bi->offset, -1,
4765 "This shall be developed in GPRS phase 2");
4769 decode_pdu_paging_ps(build_info_t *bi) {
4770 bssgp_ie_t ies[] = {
4771 { BSSGP_IEI_IMSI, NULL,
4772 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
4774 { BSSGP_IEI_DRX_PARAMETERS, NULL,
4775 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4777 { BSSGP_IEI_BVCI, NULL,
4778 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4780 { BSSGP_IEI_LOCATION_AREA, NULL,
4781 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 7 },
4783 { BSSGP_IEI_ROUTING_AREA, NULL,
4784 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 },
4786 { BSSGP_IEI_BSS_AREA_INDICATION, NULL,
4787 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4789 { BSSGP_IEI_PFI, NULL,
4790 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4792 { BSSGP_IEI_ABQP, NULL,
4793 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
4795 { BSSGP_IEI_QOS_PROFILE, NULL,
4796 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 5 },
4798 { BSSGP_IEI_TMSI, "P-TMSI",
4799 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4802 bi->ul_data = FALSE;
4804 decode_pdu_general(ies, 10, bi);
4808 decode_pdu_paging_cs(build_info_t *bi) {
4809 bssgp_ie_t ies[] = {
4810 { BSSGP_IEI_IMSI, NULL,
4811 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
4813 { BSSGP_IEI_DRX_PARAMETERS, NULL,
4814 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4816 { BSSGP_IEI_BVCI, NULL,
4817 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4819 { BSSGP_IEI_LOCATION_AREA, NULL,
4820 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 7 },
4822 { BSSGP_IEI_ROUTING_AREA, NULL,
4823 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 },
4825 { BSSGP_IEI_BSS_AREA_INDICATION, NULL,
4826 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4828 { BSSGP_IEI_TLLI, NULL,
4829 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4831 { BSSGP_IEI_CHANNEL_NEEDED, NULL,
4832 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4834 { BSSGP_IEI_EMLPP_PRIORITY, NULL,
4835 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4837 { BSSGP_IEI_TMSI, NULL,
4838 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4840 { BSSGP_IEI_GLOBAL_CN_ID, NULL,
4841 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 7 },
4844 bi->ul_data = FALSE;
4846 decode_pdu_general(ies, 11, bi);
4850 decode_pdu_ra_capability_update(build_info_t *bi) {
4851 bssgp_ie_t ies[] = {
4852 { BSSGP_IEI_TLLI, NULL,
4853 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4855 { BSSGP_IEI_TAG, NULL,
4856 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4858 bi->dl_data = FALSE;
4861 decode_pdu_general(ies, 2, bi);
4865 decode_pdu_ra_capability_update_ack(build_info_t *bi) {
4866 bssgp_ie_t ies[] = {
4867 { BSSGP_IEI_TLLI, NULL,
4868 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4870 { BSSGP_IEI_TAG, NULL,
4871 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4873 { BSSGP_IEI_IMSI, NULL,
4874 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
4876 { BSSGP_IEI_RA_CAP_UPD_CAUSE, NULL,
4877 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4879 { BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY, NULL,
4880 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN},
4883 bi->ul_data = FALSE;
4885 decode_pdu_general(ies, 5, bi);
4889 decode_pdu_radio_status(build_info_t *bi) {
4890 bssgp_ie_t ies[] = {
4891 { BSSGP_IEI_TLLI, NULL,
4892 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4894 { BSSGP_IEI_TMSI, NULL,
4895 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4897 { BSSGP_IEI_IMSI, NULL,
4898 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
4900 { BSSGP_IEI_RADIO_CAUSE, NULL,
4901 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4903 bi->dl_data = FALSE;
4906 decode_pdu_general(ies, 4, bi);
4910 decode_pdu_suspend(build_info_t *bi) {
4911 bssgp_ie_t ies[] = {
4912 { BSSGP_IEI_TLLI, NULL,
4913 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4915 { BSSGP_IEI_ROUTING_AREA, NULL,
4916 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 },
4918 bi->dl_data = FALSE;
4921 decode_pdu_general(ies, 2, bi);
4925 decode_pdu_suspend_ack(build_info_t *bi) {
4926 bssgp_ie_t ies[] = {
4927 { BSSGP_IEI_TLLI, NULL,
4928 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4930 { BSSGP_IEI_ROUTING_AREA, NULL,
4931 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 },
4933 { BSSGP_IEI_SUSPEND_REFERENCE_NUMBER, NULL,
4934 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4937 bi->ul_data = FALSE;
4939 decode_pdu_general(ies, 3, bi);
4943 decode_pdu_suspend_nack(build_info_t *bi) {
4944 bssgp_ie_t ies[] = {
4945 { BSSGP_IEI_TLLI, NULL,
4946 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4948 { BSSGP_IEI_ROUTING_AREA, NULL,
4949 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 },
4951 { BSSGP_IEI_CAUSE, NULL,
4952 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4955 bi->ul_data = FALSE;
4957 decode_pdu_general(ies, 3, bi);
4961 decode_pdu_resume(build_info_t *bi) {
4962 bssgp_ie_t ies[] = {
4963 { BSSGP_IEI_TLLI, NULL,
4964 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4966 { BSSGP_IEI_ROUTING_AREA, NULL,
4967 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 },
4969 { BSSGP_IEI_SUSPEND_REFERENCE_NUMBER, NULL,
4970 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4972 bi->dl_data = FALSE;
4975 decode_pdu_general(ies, 3, bi);
4979 decode_pdu_resume_ack(build_info_t *bi) {
4980 bssgp_ie_t ies[] = {
4981 { BSSGP_IEI_TLLI, NULL,
4982 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4984 { BSSGP_IEI_ROUTING_AREA, NULL,
4985 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 },
4989 bi->ul_data = FALSE;
4991 decode_pdu_general(ies, 2, bi);
4995 decode_pdu_resume_nack(build_info_t *bi) {
4996 bssgp_ie_t ies[] = {
4997 { BSSGP_IEI_TLLI, NULL,
4998 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5000 { BSSGP_IEI_ROUTING_AREA, NULL,
5001 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 },
5003 { BSSGP_IEI_CAUSE, NULL,
5004 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5007 bi->ul_data = FALSE;
5009 decode_pdu_general(ies, 3, bi);
5013 decode_pdu_bvc_block(build_info_t *bi) {
5014 bssgp_ie_t ies[] = {
5015 { BSSGP_IEI_BVCI, NULL,
5016 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5018 { BSSGP_IEI_CAUSE, NULL,
5019 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5021 bi->dl_data = FALSE;
5024 decode_pdu_general(ies, 2, bi);
5028 decode_pdu_bvc_block_ack(build_info_t *bi) {
5029 bssgp_ie_t ies[] = {
5030 { BSSGP_IEI_BVCI, NULL,
5031 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4},
5034 bi->ul_data = FALSE;
5036 decode_pdu_general(ies, 1, bi);
5040 decode_pdu_bvc_reset(build_info_t *bi) {
5041 bssgp_ie_t ies[] = {
5042 { BSSGP_IEI_BVCI, NULL,
5043 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5045 { BSSGP_IEI_CAUSE, NULL,
5046 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5048 { BSSGP_IEI_CELL_IDENTIFIER, NULL,
5049 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5051 { BSSGP_IEI_FEATURE_BITMAP, NULL,
5052 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5057 decode_pdu_general(ies, 4, bi);
5061 decode_pdu_bvc_reset_ack(build_info_t *bi) {
5062 bssgp_ie_t ies[] = {
5063 { BSSGP_IEI_BVCI, NULL,
5064 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5066 { BSSGP_IEI_CELL_IDENTIFIER, NULL,
5067 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5069 { BSSGP_IEI_FEATURE_BITMAP, NULL,
5070 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5075 decode_pdu_general(ies, 3, bi);
5079 decode_pdu_bvc_unblock(build_info_t *bi) {
5080 bssgp_ie_t ies[] = {
5081 { BSSGP_IEI_BVCI, NULL,
5082 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5084 bi->dl_data = FALSE;
5087 decode_pdu_general(ies, 1, bi);
5091 decode_pdu_bvc_unblock_ack(build_info_t *bi) {
5092 bssgp_ie_t ies[] = {
5093 { BSSGP_IEI_BVCI, NULL,
5094 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5097 bi->ul_data = FALSE;
5099 decode_pdu_general(ies, 1, bi);
5103 decode_pdu_flow_control_bvc(build_info_t *bi) {
5104 bssgp_ie_t ies[] = {
5105 { BSSGP_IEI_TAG, NULL,
5106 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5108 { BSSGP_IEI_BVC_BUCKET_SIZE, NULL,
5109 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5111 { BSSGP_IEI_BUCKET_LEAK_RATE, NULL,
5112 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5114 { BSSGP_IEI_BMAX_DEFAULT_MS, NULL,
5115 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5117 { BSSGP_IEI_R_DEFAULT_MS, NULL,
5118 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5120 { BSSGP_IEI_BUCKET_FULL_RATIO, NULL,
5121 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5123 { BSSGP_IEI_BVC_MEASUREMENT, NULL,
5124 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5126 bi->dl_data = FALSE;
5129 decode_pdu_general(ies, 7, bi);
5133 decode_pdu_flow_control_bvc_ack(build_info_t *bi) {
5134 bssgp_ie_t ies[] = {
5135 { BSSGP_IEI_TAG, NULL,
5136 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5139 bi->ul_data = FALSE;
5141 decode_pdu_general(ies, 1, bi);
5145 decode_pdu_flow_control_ms(build_info_t *bi) {
5146 bssgp_ie_t ies[] = {
5147 { BSSGP_IEI_TLLI, NULL,
5148 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5150 { BSSGP_IEI_TAG, NULL,
5151 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5153 { BSSGP_IEI_MS_BUCKET_SIZE, NULL,
5154 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5156 { BSSGP_IEI_BUCKET_LEAK_RATE, NULL,
5157 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5159 { BSSGP_IEI_BUCKET_FULL_RATIO, NULL,
5160 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5162 bi->dl_data = FALSE;
5165 decode_pdu_general(ies, 5, bi);
5169 decode_pdu_flow_control_ms_ack(build_info_t *bi) {
5170 bssgp_ie_t ies[] = {
5171 { BSSGP_IEI_TLLI, NULL,
5172 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5174 { BSSGP_IEI_TAG, NULL,
5175 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5178 bi->ul_data = FALSE;
5180 decode_pdu_general(ies, 2, bi);
5184 decode_pdu_flush_ll(build_info_t *bi) {
5185 bssgp_ie_t ies[] = {
5186 { BSSGP_IEI_TLLI, NULL,
5187 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5189 { BSSGP_IEI_BVCI, "BVCI (old)",
5190 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5192 { BSSGP_IEI_BVCI, "BVCI (new)",
5193 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5195 { BSSGP_IEI_NSEI, "NSEI (new)",
5196 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5199 bi->ul_data = FALSE;
5201 decode_pdu_general(ies, 4, bi);
5205 decode_pdu_flush_ll_ack(build_info_t *bi) {
5206 bssgp_ie_t ies[] = {
5207 { BSSGP_IEI_TLLI, NULL,
5208 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5210 { BSSGP_IEI_FLUSH_ACTION, NULL,
5211 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5213 { BSSGP_IEI_BVCI, "BVCI (new)",
5214 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5216 { BSSGP_IEI_NUMBER_OF_OCTETS_AFFECTED, NULL,
5217 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 5 },
5219 { BSSGP_IEI_NSEI, "NSEI (new)",
5220 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5222 bi->dl_data = FALSE;
5225 decode_pdu_general(ies, 5, bi);
5229 decode_pdu_llc_discarded(build_info_t *bi) {
5230 bssgp_ie_t ies[] = {
5231 { BSSGP_IEI_TLLI, NULL,
5232 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5234 { BSSGP_IEI_LLC_FRAMES_DISCARDED, NULL,
5235 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5237 { BSSGP_IEI_BVCI, NULL,
5238 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5240 { BSSGP_IEI_NUMBER_OF_OCTETS_AFFECTED, "Number of octets deleted",
5241 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 5 },
5243 { BSSGP_IEI_PFI, NULL,
5244 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5246 bi->dl_data = FALSE;
5249 decode_pdu_general(ies, 5, bi);
5253 decode_pdu_flow_control_pfc(build_info_t *bi) {
5254 bssgp_ie_t ies[] = {
5255 { BSSGP_IEI_TLLI, NULL,
5256 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5258 { BSSGP_IEI_TAG, NULL,
5259 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5261 { BSSGP_IEI_MS_BUCKET_SIZE, NULL,
5262 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5264 { BSSGP_IEI_BUCKET_LEAK_RATE, NULL,
5265 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5267 { BSSGP_IEI_BUCKET_FULL_RATIO, NULL,
5268 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5270 { BSSGP_IEI_PFC_FLOW_CONTROL_PARAMETERS, NULL,
5271 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5273 bi->dl_data = FALSE;
5276 decode_pdu_general(ies, 6, bi);
5280 decode_pdu_flow_control_pfc_ack(build_info_t *bi) {
5281 bssgp_ie_t ies[] = {
5282 { BSSGP_IEI_TLLI, NULL,
5283 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5285 { BSSGP_IEI_TAG, NULL,
5286 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5289 bi->ul_data = FALSE;
5291 decode_pdu_general(ies, 2, bi);
5295 decode_pdu_sgsn_invoke_trace(build_info_t *bi) {
5296 bssgp_ie_t ies[] = {
5297 { BSSGP_IEI_TRACE_TYPE, NULL,
5298 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5300 { BSSGP_IEI_TRACE_REFERENCE, NULL,
5301 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5303 { BSSGP_IEI_TRIGGER_ID, NULL,
5304 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5306 { BSSGP_IEI_MOBILE_ID, NULL,
5307 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5309 { BSSGP_IEI_OMC_ID, NULL,
5310 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5312 { BSSGP_IEI_TRANSACTION_ID, NULL,
5313 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5316 bi->ul_data = FALSE;
5318 decode_pdu_general(ies, 6, bi);
5322 decode_pdu_status(build_info_t *bi) {
5323 bssgp_ie_t ies[] = {
5324 { BSSGP_IEI_CAUSE, NULL,
5325 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5327 { BSSGP_IEI_BVCI, NULL,
5328 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5330 { BSSGP_IEI_PDU_IN_ERROR, NULL,
5331 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5336 decode_pdu_general(ies, 3, bi);
5340 decode_pdu_download_bss_pfc(build_info_t *bi) {
5341 bssgp_ie_t ies[] = {
5342 { BSSGP_IEI_TLLI, NULL,
5343 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5345 { BSSGP_IEI_PFI, NULL,
5346 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5348 bi->dl_data = FALSE;
5351 decode_pdu_general(ies, 2, bi);
5354 /* 10.4.17 CREATE-BSS-PFC */
5356 decode_pdu_create_bss_pfc(build_info_t *bi) {
5357 bssgp_ie_t ies[] = {
5358 { BSSGP_IEI_TLLI, NULL,
5359 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5361 { BSSGP_IEI_IMSI, NULL,
5362 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5364 { BSSGP_IEI_PFI, NULL,
5365 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5367 { BSSGP_IEI_GPRS_TIMER, "PFT",
5368 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5370 { BSSGP_IEI_ABQP, NULL,
5371 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5373 { BSSGP_IEI_SERVICE_UTRAN_CCO, NULL,
5374 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5376 { BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY, NULL,
5377 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5379 { BSSGP_IEI_PRIORITY, "Allocation/Retention Priority",
5380 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5382 { BSSGP_IEI_GPRS_TIMER, "T10",
5383 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5384 /* Inter RAT Handover Info 11.3.94 3GPP TS 48.018 version 6.11.0 Release 6 */
5387 bi->ul_data = FALSE;
5389 decode_pdu_general(ies, 9, bi);
5393 decode_pdu_create_bss_pfc_ack(build_info_t *bi) {
5394 bssgp_ie_t ies[] = {
5395 { BSSGP_IEI_TLLI, NULL,
5396 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5398 { BSSGP_IEI_PFI, NULL,
5399 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5401 { BSSGP_IEI_ABQP, NULL,
5402 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5404 { BSSGP_IEI_CAUSE, NULL,
5405 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5407 bi->dl_data = FALSE;
5410 decode_pdu_general(ies, 4, bi);
5414 decode_pdu_create_bss_pfc_nack(build_info_t *bi) {
5415 bssgp_ie_t ies[] = {
5416 { BSSGP_IEI_TLLI, NULL,
5417 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5419 { BSSGP_IEI_PFI, NULL,
5420 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5422 { BSSGP_IEI_CAUSE, NULL,
5423 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5425 bi->dl_data = FALSE;
5428 decode_pdu_general(ies, 3, bi);
5432 decode_pdu_modify_bss_pfc(build_info_t *bi) {
5433 bssgp_ie_t ies[] = {
5434 { BSSGP_IEI_TLLI, NULL,
5435 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5437 { BSSGP_IEI_PFI, NULL,
5438 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5440 { BSSGP_IEI_ABQP, NULL,
5441 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5443 bi->dl_data = FALSE;
5446 decode_pdu_general(ies, 3, bi);
5450 decode_pdu_modify_bss_pfc_ack(build_info_t *bi) {
5451 bssgp_ie_t ies[] = {
5452 { BSSGP_IEI_TLLI, NULL,
5453 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5455 { BSSGP_IEI_PFI, NULL,
5456 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5458 { BSSGP_IEI_GPRS_TIMER, "PFT",
5459 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5461 { BSSGP_IEI_ABQP, NULL,
5462 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5465 bi->ul_data = FALSE;
5467 decode_pdu_general(ies, 4, bi);
5471 decode_pdu_delete_bss_pfc(build_info_t *bi) {
5472 bssgp_ie_t ies[] = {
5473 { BSSGP_IEI_TLLI, NULL,
5474 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5476 { BSSGP_IEI_PFI, NULL,
5477 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5480 bi->ul_data = FALSE;
5482 decode_pdu_general(ies, 2, bi);
5486 decode_pdu_delete_bss_pfc_ack(build_info_t *bi) {
5487 bssgp_ie_t ies[] = {
5488 { BSSGP_IEI_TLLI, NULL,
5489 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5491 { BSSGP_IEI_PFI, NULL,
5492 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5494 bi->dl_data = FALSE;
5497 decode_pdu_general(ies, 2, bi);
5501 decode_pdu_delete_bss_pfc_req(build_info_t *bi) {
5502 bssgp_ie_t ies[] = {
5503 { BSSGP_IEI_TLLI, NULL,
5504 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5506 { BSSGP_IEI_PFI, NULL,
5507 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5509 { BSSGP_IEI_CAUSE, NULL,
5510 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5512 bi->dl_data = FALSE;
5515 decode_pdu_general(ies, 3, bi);
5519 decode_pdu_perform_location_request(build_info_t *bi) {
5520 bssgp_ie_t ies[] = {
5521 { BSSGP_IEI_TLLI, NULL,
5522 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5524 { BSSGP_IEI_IMSI, NULL,
5525 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5527 { BSSGP_IEI_DRX_PARAMETERS, NULL,
5528 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5530 { BSSGP_IEI_BVCI, "BVCI (PCU-PTP)",
5531 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5533 { BSSGP_IEI_NSEI, "NSEI (PCU-PTP)",
5534 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5536 { BSSGP_IEI_LOCATION_TYPE, NULL,
5537 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5539 { BSSGP_IEI_CELL_IDENTIFIER, NULL,
5540 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5542 { BSSGP_IEI_LCS_CAPABILITY, NULL,
5543 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5545 { BSSGP_IEI_LCS_PRIORITY, NULL,
5546 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5548 { BSSGP_IEI_LCS_QOS, NULL,
5549 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5551 { BSSGP_IEI_LCS_CLIENT_TYPE, NULL,
5552 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5554 { BSSGP_IEI_REQUESTED_GPS_ASSISTANCE_DATA, NULL,
5555 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5558 bi->ul_data = FALSE;
5560 decode_pdu_general(ies, 12, bi);
5564 decode_pdu_perform_location_response(build_info_t *bi) {
5565 bssgp_ie_t ies[] = {
5566 { BSSGP_IEI_TLLI, NULL,
5567 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5569 { BSSGP_IEI_BVCI, "BVCI (PCU-PTP)",
5570 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5572 { BSSGP_IEI_LOCATION_ESTIMATE, NULL,
5573 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5575 { BSSGP_IEI_POSITIONING_DATA, NULL,
5576 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5578 { BSSGP_IEI_DECIPHERING_KEYS, NULL,
5579 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5581 { BSSGP_IEI_LCS_CAUSE, NULL,
5582 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5584 bi->dl_data = FALSE;
5587 decode_pdu_general(ies, 6, bi);
5591 decode_pdu_perform_location_abort(build_info_t *bi) {
5592 bssgp_ie_t ies[] = {
5593 { BSSGP_IEI_TLLI, NULL,
5594 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5596 { BSSGP_IEI_BVCI, "BVCI (PCU-PTP)",
5597 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5599 { BSSGP_IEI_LCS_CAUSE, NULL,
5600 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5603 bi->ul_data = FALSE;
5605 decode_pdu_general(ies, 3, bi);
5609 decode_pdu_position_command(build_info_t *bi) {
5610 bssgp_ie_t ies[] = {
5611 { BSSGP_IEI_TLLI, NULL,
5612 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5614 { BSSGP_IEI_BVCI, "BVCI (PCU-PTP)",
5615 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5617 { BSSGP_IEI_RRLP_FLAGS, NULL,
5618 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5620 { BSSGP_IEI_RRLP_APDU, NULL,
5621 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5623 bi->dl_data = FALSE;
5626 decode_pdu_general(ies, 4, bi);
5630 decode_pdu_position_response(build_info_t *bi) {
5631 bssgp_ie_t ies[] = {
5632 { BSSGP_IEI_TLLI, NULL,
5633 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5635 { BSSGP_IEI_BVCI, "BVCI (PCU-PTP)",
5636 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5638 { BSSGP_IEI_RRLP_FLAGS, NULL,
5639 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5641 { BSSGP_IEI_RRLP_APDU, NULL,
5642 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5644 { BSSGP_IEI_LCS_CAUSE, NULL,
5645 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5648 bi->ul_data = FALSE;
5650 decode_pdu_general(ies, 5, bi);
5655 decode_pdu_ran_information(build_info_t *bi) {
5656 bssgp_ie_t ies[] = {
5658 { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Destination Cell Identifier",
5659 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5661 { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Source Cell Identifier",
5662 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5664 { BSSGP_IEI_RAN_INFORMATION_CONTAINER_UNIT, "RAN-INFORMATION RIM Container",
5665 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 2 },
5667 { BSSGP_IEI_RIM_APPLICATION_IDENTITY, "Application Identity",
5668 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5670 { BSSGP_IEI_RIM_SEQUENCE_NUMBER, "Sequence Number",
5671 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5673 { BSSGP_IEI_RIM_PDU_INDICATIONS, "PDU Indications",
5674 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5676 { BSSGP_IEI_RIM_PROTOCOL_VERSION, "Protocol Version",
5677 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5679 { BSSGP_IEI_RAN_INFORMATION_APPLICATION_CONTAINER, "RAN-INFORMATION RIM Container",
5680 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5687 decode_pdu_general(ies, 8, bi);
5691 decode_pdu_ran_information_request(build_info_t *bi) {
5693 bssgp_ie_t ies[] = {
5695 { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Destination Cell Identifier",
5696 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5698 { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Source Cell Identifier",
5699 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5701 { BSSGP_IEI_RAN_INFORMATION_REQUEST_CONTAINER_UNIT, "RAN-INFORMATION-REQUEST RIM Container",
5702 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 2 },
5704 { BSSGP_IEI_RIM_APPLICATION_IDENTITY, "Application Identity",
5705 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5707 { BSSGP_IEI_RIM_SEQUENCE_NUMBER, "Sequence Number",
5708 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5710 { BSSGP_IEI_RIM_PDU_INDICATIONS, "PDU Indications",
5711 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5713 { BSSGP_IEI_RIM_PROTOCOL_VERSION, "Protocol Version",
5714 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5716 { BSSGP_IEI_RAN_INFORMATION_REQUEST_APPLICATION_CONTAINER, "RAN-INFORMATION-REQUEST Application Container",
5717 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5724 decode_pdu_general(ies, 8, bi);
5729 decode_pdu_ran_information_ack(build_info_t *bi) {
5730 bssgp_ie_t ies[] = {
5731 { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Destination Cell Identifier",
5732 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5734 { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Source Cell Identifier",
5735 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5737 { BSSGP_IEI_RAN_INFORMATION_REQUEST_CONTAINER_UNIT, "RAN-INFORMATION-ACK RIM Container",
5738 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 2 },
5740 { BSSGP_IEI_RIM_APPLICATION_IDENTITY, "Application Identity",
5741 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5743 { BSSGP_IEI_RIM_SEQUENCE_NUMBER, "Sequence Number",
5744 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5746 { BSSGP_IEI_RIM_PROTOCOL_VERSION, "Protocol Version",
5747 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5753 decode_pdu_general(ies, 6, bi);
5757 decode_pdu_ran_information_error(build_info_t *bi) {
5758 bssgp_ie_t ies[] = {
5759 { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Destination Cell Identifier",
5760 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5762 { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Source Cell Identifier",
5763 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5765 { BSSGP_IEI_RAN_INFORMATION_REQUEST_CONTAINER_UNIT, "RAN-INFORMATION-ERROR RIM Container",
5766 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 2 },
5768 { BSSGP_IEI_RIM_APPLICATION_IDENTITY, "Application Identity",
5769 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5771 { BSSGP_IEI_CAUSE, "RIM Cause",
5772 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5774 { BSSGP_IEI_RIM_PROTOCOL_VERSION, "Protocol Version",
5775 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5777 { BSSGP_IEI_PDU_IN_ERROR, NULL,
5778 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5783 decode_pdu_general(ies, 7, bi);
5787 decode_pdu_ran_information_application_error(build_info_t *bi) {
5788 bssgp_ie_t ies[] = {
5789 { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Destination Cell Identifier",
5790 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5792 { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Source Cell Identifier",
5793 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5795 { BSSGP_IEI_RAN_INFORMATION_REQUEST_CONTAINER_UNIT, "RAN-INFORMATION-APPLICATION RIM Container",
5796 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 2 },
5798 { BSSGP_IEI_RIM_APPLICATION_IDENTITY, "Application Identity",
5799 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5801 /* pdu indication, I hope RIM_PDU_INDICATIONS decode it right, it use the same IEI so it should... */
5802 { BSSGP_IEI_RIM_PDU_INDICATIONS, "PDU Indications",
5803 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5805 { BSSGP_IEI_RIM_SEQUENCE_NUMBER, "Sequence Number",
5806 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5808 { BSSGP_IEI_RIM_PROTOCOL_VERSION, "Protocol Version",
5809 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5811 { BSSGP_IEI_APPLICATION_ERROR_CONTAINER, NULL,
5812 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5818 decode_pdu_general(ies, 8, bi);
5823 decode_pdu(build_info_t *bi) {
5825 switch (bi->pdutype) {
5826 case BSSGP_PDU_DL_UNITDATA:
5827 decode_pdu_dl_unitdata(bi);
5829 case BSSGP_PDU_UL_UNITDATA:
5830 decode_pdu_ul_unitdata(bi);
5832 case BSSGP_PDU_RA_CAPABILITY:
5833 decode_pdu_ra_capability(bi);
5835 case BSSGP_PDU_PTM_UNITDATA:
5836 decode_pdu_ptm_unitdata(bi);
5838 case BSSGP_PDU_PAGING_PS:
5839 decode_pdu_paging_ps(bi);
5841 case BSSGP_PDU_PAGING_CS:
5842 decode_pdu_paging_cs(bi);
5844 case BSSGP_PDU_RA_CAPABILITY_UPDATE:
5845 decode_pdu_ra_capability_update(bi);
5847 case BSSGP_PDU_RA_CAPABILITY_UPDATE_ACK:
5848 decode_pdu_ra_capability_update_ack(bi);
5850 case BSSGP_PDU_RADIO_STATUS:
5851 decode_pdu_radio_status(bi);
5853 case BSSGP_PDU_SUSPEND:
5854 decode_pdu_suspend(bi);
5856 case BSSGP_PDU_SUSPEND_ACK:
5857 decode_pdu_suspend_ack(bi);
5859 case BSSGP_PDU_SUSPEND_NACK:
5860 decode_pdu_suspend_nack(bi);
5862 case BSSGP_PDU_RESUME:
5863 decode_pdu_resume(bi);
5865 case BSSGP_PDU_RESUME_ACK:
5866 decode_pdu_resume_ack(bi);
5868 case BSSGP_PDU_RESUME_NACK:
5869 decode_pdu_resume_nack(bi);
5871 case BSSGP_PDU_BVC_BLOCK:
5872 decode_pdu_bvc_block(bi);
5874 case BSSGP_PDU_BVC_BLOCK_ACK:
5875 decode_pdu_bvc_block_ack(bi);
5877 case BSSGP_PDU_BVC_RESET:
5878 decode_pdu_bvc_reset(bi);
5880 case BSSGP_PDU_BVC_RESET_ACK:
5881 decode_pdu_bvc_reset_ack(bi);
5883 case BSSGP_PDU_BVC_UNBLOCK:
5884 decode_pdu_bvc_unblock(bi);
5886 case BSSGP_PDU_BVC_UNBLOCK_ACK:
5887 decode_pdu_bvc_unblock_ack(bi);
5889 case BSSGP_PDU_FLOW_CONTROL_BVC:
5890 decode_pdu_flow_control_bvc(bi);
5892 case BSSGP_PDU_FLOW_CONTROL_BVC_ACK:
5893 decode_pdu_flow_control_bvc_ack(bi);
5895 case BSSGP_PDU_FLOW_CONTROL_MS:
5896 decode_pdu_flow_control_ms(bi);
5898 case BSSGP_PDU_FLOW_CONTROL_MS_ACK:
5899 decode_pdu_flow_control_ms_ack(bi);
5901 case BSSGP_PDU_FLUSH_LL:
5902 decode_pdu_flush_ll(bi);
5904 case BSSGP_PDU_FLUSH_LL_ACK:
5905 decode_pdu_flush_ll_ack(bi);
5907 case BSSGP_PDU_LLC_DISCARDED:
5908 decode_pdu_llc_discarded(bi);
5910 case BSSGP_PDU_FLOW_CONTROL_PFC:
5911 decode_pdu_flow_control_pfc(bi);
5913 case BSSGP_PDU_FLOW_CONTROL_PFC_ACK:
5914 decode_pdu_flow_control_pfc_ack(bi);
5916 case BSSGP_PDU_SGSN_INVOKE_TRACE:
5917 decode_pdu_sgsn_invoke_trace(bi);
5919 case BSSGP_PDU_STATUS:
5920 decode_pdu_status(bi);
5922 case BSSGP_PDU_DOWNLOAD_BSS_PFC:
5923 decode_pdu_download_bss_pfc(bi);
5925 case BSSGP_PDU_CREATE_BSS_PFC:
5926 decode_pdu_create_bss_pfc(bi);
5928 case BSSGP_PDU_CREATE_BSS_PFC_ACK:
5929 decode_pdu_create_bss_pfc_ack(bi);
5931 case BSSGP_PDU_CREATE_BSS_PFC_NACK:
5932 decode_pdu_create_bss_pfc_nack(bi);
5934 case BSSGP_PDU_MODIFY_BSS_PFC:
5935 decode_pdu_modify_bss_pfc(bi);
5937 case BSSGP_PDU_MODIFY_BSS_PFC_ACK:
5938 decode_pdu_modify_bss_pfc_ack(bi);
5940 case BSSGP_PDU_DELETE_BSS_PFC:
5941 decode_pdu_delete_bss_pfc(bi);
5943 case BSSGP_PDU_DELETE_BSS_PFC_ACK:
5944 decode_pdu_delete_bss_pfc_ack(bi);
5946 case BSSGP_PDU_DELETE_BSS_PFC_REQ:
5947 decode_pdu_delete_bss_pfc_req(bi);
5949 case BSSGP_PDU_PERFORM_LOCATION_REQUEST:
5950 decode_pdu_perform_location_request(bi);
5952 case BSSGP_PDU_PERFORM_LOCATION_RESPONSE:
5953 decode_pdu_perform_location_response(bi);
5955 case BSSGP_PDU_PERFORM_LOCATION_ABORT:
5956 decode_pdu_perform_location_abort(bi);
5958 case BSSGP_PDU_POSITION_COMMAND:
5959 decode_pdu_position_command(bi);
5961 case BSSGP_PDU_POSITION_RESPONSE:
5962 decode_pdu_position_response(bi);
5964 case BSSGP_PDU_RAN_INFORMATION:
5965 decode_pdu_ran_information(bi);
5967 case BSSGP_PDU_RAN_INFORMATION_REQUEST:
5968 decode_pdu_ran_information_request(bi);
5970 case BSSGP_PDU_RAN_INFORMATION_ACK:
5971 decode_pdu_ran_information_ack(bi);
5973 case BSSGP_PDU_RAN_APPLICATION_ERROR:
5974 decode_pdu_ran_information_application_error(bi);
5976 case BSSGP_PDU_RAN_INFORMATION_ERROR:
5977 decode_pdu_ran_information_error(bi);
5985 dissect_bssgp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5987 build_info_t bi = { NULL, 0, NULL, NULL, NULL, FALSE, FALSE, 0 };
5990 proto_tree *bssgp_tree;
5994 bi.parent_tree = tree;
5996 pinfo->current_proto = "BSSGP";
5998 if (check_col(pinfo->cinfo, COL_PROTOCOL))
5999 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BSSGP");
6001 if (check_col(pinfo->cinfo, COL_INFO))
6002 col_clear(pinfo->cinfo, COL_INFO);
6004 bi.pdutype = tvb_get_guint8(tvb, 0);
6008 ti = proto_tree_add_item(tree, proto_bssgp, tvb, 0, -1, FALSE);
6009 bssgp_tree = proto_item_add_subtree(ti, ett_bssgp);
6010 proto_tree_add_uint_format_value(bssgp_tree, hf_bssgp_pdu_type, tvb, 0, 1,
6013 val_to_str(bi.pdutype, tab_bssgp_pdu_types,
6014 "Unknown"), bi.pdutype);
6015 bi.bssgp_tree = bssgp_tree;
6018 if (check_col(pinfo->cinfo, COL_INFO)) {
6019 col_add_str(pinfo->cinfo, COL_INFO, val_to_str(bi.pdutype,
6020 tab_bssgp_pdu_types,
6021 "Unknown PDU type"));
6027 proto_register_bssgp(void)
6029 static hf_register_info hf[] = {
6030 { &hf_bssgp_pdu_type,
6031 { "PDU Type", "bssgp.pdu_type",
6032 FT_UINT8, BASE_HEX, VALS(tab_bssgp_pdu_types), 0x0,
6035 { &hf_bssgp_iei_nacc_cause,
6036 { "NACC Cause", "bssgp.iei.nacc_cause",
6037 FT_UINT8, BASE_HEX, VALS(tab_nacc_cause), 0x0,
6040 { &hf_bssgp_ie_type,
6041 { "IE Type", "bssgp.ie_type",
6042 FT_UINT8, BASE_HEX, VALS(tab_bssgp_ie_types), 0x0,
6043 "Information element type", HFILL }
6046 { "BVCI", "bssgp.bvci",
6047 FT_UINT16, BASE_HEX, NULL, 0x0,
6051 { "TLLI", "bssgp.tlli",
6052 FT_UINT32, BASE_HEX, NULL, 0x0,
6056 { "NSEI", "bssgp.nsei",
6057 FT_UINT16, BASE_HEX, NULL, 0x0,
6061 { "MCC", "bssgp.mcc",
6062 FT_UINT8, BASE_DEC, VALS(E212_codes), 0x0,
6066 { "MNC", "bssgp.mnc",
6067 FT_UINT8, BASE_DEC, NULL, 0x0,
6071 { "LAC", "bssgp.lac",
6072 FT_UINT16, BASE_DEC, NULL, 0x0,
6076 { "RAC", "bssgp.rac",
6077 FT_UINT8, BASE_DEC, NULL, 0x0,
6082 FT_UINT16, BASE_HEX, NULL, 0x0,
6083 "Cell Identity", HFILL }
6085 { &hf_bssgp_ra_discriminator,
6086 { "Routing Address Discriminator", "bssgp.rad",
6087 FT_UINT8, BASE_DEC, VALS(ra_discriminator_vals), 0x0f,
6091 { "Application ID", "bssgp.appid",
6092 FT_UINT8, BASE_HEX, NULL, 0x0,
6096 { "Reporting Cell Identity", "bssgp.rcid",
6097 FT_UINT64, BASE_HEX, NULL, 0x0,
6100 { &hf_bssgp_rrc_si_msg_type,
6101 { "RRC SI type", "bssgp.rrc_si_type",
6102 FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_rr_strings), 0x0,
6105 { &hf_ran_inf_req_pdu_type_ext,
6106 { "PDU Type Extension", "bssgp.ran_inf_req_pdu_type_ext",
6107 FT_UINT8, BASE_DEC, VALS(ran_inf_req_pdu_type_ext_vals), 0x0e,
6110 { &hf_ran_inf_pdu_type_ext,
6111 { "PDU Type Extension", "bssgp.ran_req_pdu_type_ext",
6112 FT_UINT8, BASE_DEC, VALS(ran_inf_pdu_type_ext_vals), 0x0e,
6115 { &hf_bssgp_tmsi_ptmsi,
6116 { "TMSI/PTMSI", "bssgp.tmsi_ptmsi",
6117 FT_UINT32, BASE_HEX, NULL, 0x0,
6121 { "IMSI", "bssgp.imsi",
6122 FT_STRING, BASE_NONE, NULL, 0x0,
6126 { "IMEI", "bssgp.imei",
6127 FT_STRING, BASE_NONE, NULL, 0x0,
6131 { "IMEISV", "bssgp.imeisv",
6132 FT_STRING, BASE_NONE, NULL, 0x0,
6136 { "NRI", "bssgp.nri",
6137 FT_UINT16, BASE_DEC, NULL, 0x0,
6142 /* Setup protocol subtree array */
6143 static gint *ett[] = {
6145 &ett_bssgp_qos_profile,
6146 &ett_bssgp_gprs_timer,
6147 &ett_bssgp_cell_identifier,
6148 &ett_bssgp_channel_needed,
6149 &ett_bssgp_drx_parameters,
6150 &ett_bssgp_mobile_identity,
6151 &ett_bssgp_priority,
6152 &ett_bssgp_lsa_identifier_list,
6153 &ett_bssgp_lsa_information,
6154 &ett_bssgp_lsa_information_lsa_identification_and_attributes,
6157 &ett_bssgp_lcs_client_type,
6158 &ett_bssgp_requested_gps_assistance_data,
6159 &ett_bssgp_requested_gps_assistance_data_satellite,
6160 &ett_bssgp_location_type,
6161 &ett_bssgp_positioning_data_positioning_method,
6162 &ett_bssgp_lcs_cause,
6163 &ett_bssgp_lcs_capability,
6164 &ett_bssgp_rrlp_flags,
6165 &ett_bssgp_rim_pdu_indications,
6168 &ett_bssgp_routing_area,
6169 &ett_bssgp_location_area,
6171 &ett_bssgp_ran_information_request_application_container,
6172 &ett_bssgp_rim_routing_information,
6173 &ett_bssgp_ran_information_request_container_unit,
6174 &ett_bssgp_ran_information_container_unit,
6175 &ett_bssgp_pfc_flow_control_parameters,
6176 &ett_bssgp_pfc_flow_control_parameters_pfc,
6177 &ett_bssgp_global_cn_id,
6178 &ett_bssgp_ms_radio_access_capability,
6179 &ett_bssgp_feature_bitmap,
6180 &ett_bssgp_positioning_data,
6181 &ett_bssgp_msrac_value_part,
6182 &ett_bssgp_msrac_additional_access_technologies,
6183 &ett_bssgp_msrac_access_capabilities,
6184 &ett_bssgp_msrac_a5_bits,
6185 &ett_bssgp_msrac_multislot_capability,
6187 &ett_bssgp_tmsi_ptmsi,
6190 /* Register the protocol name and description */
6191 proto_bssgp = proto_register_protocol("Base Station Subsystem GPRS Protocol", "BSSGP", "bssgp");
6193 /* Required function calls to register the header fields and subtrees used */
6194 proto_register_field_array(proto_bssgp, hf, array_length(hf));
6195 proto_register_subtree_array(ett, array_length(ett));
6196 register_dissector("bssgp", dissect_bssgp, proto_bssgp);
6198 /* Register configuration options */
6199 bssgp_module = prefs_register_protocol(proto_bssgp, NULL);
6200 prefs_register_bool_preference(bssgp_module, "decode_nri",
6202 "Decode NRI (for use with SGSN in Pool)",
6204 prefs_register_uint_preference(bssgp_module, "nri_length", "NRI length",
6205 "NRI length, in bits",
6206 10, &bssgp_nri_length);
6209 /* If this dissector uses sub-dissector registration add a registration routine.
6212 proto_reg_handoff_bssgp(void)
6214 llc_handle = find_dissector("llcgprs");
6215 rrlp_handle = find_dissector("rrlp");
6216 data_handle = find_dissector("data");