2 * Routines for Base Station Subsystem GPRS Protocol dissection
3 * Copyright 2000, Susanne Edlund <susanne.edlund@ericsson.com>
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
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 /*#define BSSGP_DEBUG*/
41 #define BSSGP_LITTLE_ENDIAN FALSE
42 #define BSSGP_TRANSLATION_MAX_LEN 50
43 #define BSSGP_MASK_LEFT_OCTET_HALF 0xf0
44 #define BSSGP_MASK_RIGHT_OCTET_HALF 0x0f
45 #define BSSGP_MOBILE_IDENTITY_TYPE_IMSI 1
46 #define BSSGP_MOBILE_IDENTITY_TYPE_IMEI 2
47 #define BSSGP_MOBILE_IDENTITY_TYPE_IMEISV 3
48 #define BSSGP_MOBILE_IDENTITY_TYPE_TMSI_PTMSI 4
49 #define BSSGP_MOBILE_IDENTITY_TYPE_NO_IDENTITY 0
50 #define BSSGP_SEP ", "
51 #define BSSGP_NOT_DECODED "< Not decoded yet >"
52 #define BSSGP_UNKNOWN (-1)
53 static int bssgp_decode_nri = 0;
54 static guint bssgp_nri_length = 4;
56 static dissector_handle_t bssgp_handle;
57 static dissector_handle_t llc_handle;
58 static dissector_handle_t rrlp_handle;
59 static dissector_handle_t data_handle;
61 module_t *bssgp_module;
62 void proto_reg_handoff_bssgp(void);
64 /* Initialize the protocol and registered fields */
65 static int proto_bssgp = -1;
66 static int hf_bssgp_pdu_type = -1;
67 static int hf_bssgp_ie_type = -1;
68 static int hf_bssgp_mcc = -1;
69 static int hf_bssgp_mnc = -1;
70 static int hf_bssgp_lac = -1;
71 static int hf_bssgp_rac = -1;
72 static int hf_bssgp_ci = -1;
73 static int hf_bssgp_nri = -1;
74 static int hf_bssgp_imsi = -1;
75 static int hf_bssgp_imei = -1;
76 static int hf_bssgp_imeisv = -1;
77 static int hf_bssgp_tmsi_ptmsi = -1;
78 static int hf_bssgp_bvci = -1;
79 static int hf_bssgp_nsei = -1;
80 static int hf_bssgp_tlli = -1;
82 /* Initialize the subtree pointers */
83 static gint ett_bssgp = -1;
84 static gint ett_bssgp_qos_profile = -1;
85 static gint ett_bssgp_gprs_timer = -1;
86 static gint ett_bssgp_cell_identifier = -1;
87 static gint ett_bssgp_channel_needed = -1;
88 static gint ett_bssgp_drx_parameters = -1;
89 static gint ett_bssgp_mobile_identity = -1;
90 static gint ett_bssgp_priority = -1;
91 static gint ett_bssgp_lsa_identifier_list = -1;
92 static gint ett_bssgp_lsa_information = -1;
93 static gint ett_bssgp_lsa_information_lsa_identification_and_attributes = -1;
94 static gint ett_bssgp_abqp = -1;
95 static gint ett_bssgp_lcs_qos = -1;
96 static gint ett_bssgp_lcs_client_type = -1;
97 static gint ett_bssgp_requested_gps_assistance_data = -1;
98 static gint ett_bssgp_requested_gps_assistance_data_satellite = -1;
99 static gint ett_bssgp_location_type = -1;
100 static gint ett_bssgp_positioning_data_positioning_method = -1;
101 static gint ett_bssgp_deciphering_keys = -1;
102 static gint ett_bssgp_lcs_cause = -1;
103 static gint ett_bssgp_lcs_capability = -1;
104 static gint ett_bssgp_rrlp_flags = -1;
105 static gint ett_bssgp_ran_information_indications = -1;
106 static gint ett_bssgp_mcc = -1;
107 static gint ett_bssgp_mnc = -1;
108 static gint ett_bssgp_routeing_area = -1;
109 static gint ett_bssgp_location_area = -1;
110 static gint ett_bssgp_rai_ci = -1;
111 static gint ett_bssgp_ran_information_request_container_unit = -1;
112 static gint ett_bssgp_ran_information_container_unit = -1;
113 static gint ett_bssgp_pfc_flow_control_parameters = -1;
114 static gint ett_bssgp_pfc_flow_control_parameters_pfc = -1;
115 static gint ett_bssgp_global_cn_id = -1;
116 static gint ett_bssgp_ms_radio_access_capability = -1;
117 static gint ett_bssgp_msrac_value_part = -1;
118 static gint ett_bssgp_msrac_additional_access_technologies = -1;
119 static gint ett_bssgp_msrac_access_capabilities = -1;
120 static gint ett_bssgp_msrac_a5_bits = -1;
121 static gint ett_bssgp_msrac_multislot_capability = -1;
122 static gint ett_bssgp_feature_bitmap = -1;
123 static gint ett_bssgp_positioning_data = -1;
124 static gint ett_bssgp_tlli = -1;
126 /* PDU type coding, v6.5.0, table 11.3.26, p 80 */
127 #define BSSGP_PDU_DL_UNITDATA 0x00
128 #define BSSGP_PDU_UL_UNITDATA 0x01
129 #define BSSGP_PDU_RA_CAPABILITY 0x02
130 #define BSSGP_PDU_PTM_UNITDATA 0x03
131 #define BSSGP_PDU_PAGING_PS 0x06
132 #define BSSGP_PDU_PAGING_CS 0x07
133 #define BSSGP_PDU_RA_CAPABILITY_UPDATE 0x08
134 #define BSSGP_PDU_RA_CAPABILITY_UPDATE_ACK 0x09
135 #define BSSGP_PDU_RADIO_STATUS 0x0a
136 #define BSSGP_PDU_SUSPEND 0x0b
137 #define BSSGP_PDU_SUSPEND_ACK 0x0c
138 #define BSSGP_PDU_SUSPEND_NACK 0x0d
139 #define BSSGP_PDU_RESUME 0x0e
140 #define BSSGP_PDU_RESUME_ACK 0x0f
141 #define BSSGP_PDU_RESUME_NACK 0x10
142 #define BSSGP_PDU_BVC_BLOCK 0x20
143 #define BSSGP_PDU_BVC_BLOCK_ACK 0x21
144 #define BSSGP_PDU_BVC_RESET 0x22
145 #define BSSGP_PDU_BVC_RESET_ACK 0x23
146 #define BSSGP_PDU_BVC_UNBLOCK 0x24
147 #define BSSGP_PDU_BVC_UNBLOCK_ACK 0x25
148 #define BSSGP_PDU_FLOW_CONTROL_BVC 0x26
149 #define BSSGP_PDU_FLOW_CONTROL_BVC_ACK 0x27
150 #define BSSGP_PDU_FLOW_CONTROL_MS 0x28
151 #define BSSGP_PDU_FLOW_CONTROL_MS_ACK 0x29
152 #define BSSGP_PDU_FLUSH_LL 0x2a
153 #define BSSGP_PDU_FLUSH_LL_ACK 0x2b
154 #define BSSGP_PDU_LLC_DISCARDED 0x2c
155 #define BSSGP_PDU_FLOW_CONTROL_PFC 0x2d
156 #define BSSGP_PDU_FLOW_CONTROL_PFC_ACK 0x2e
157 #define BSSGP_PDU_SGSN_INVOKE_TRACE 0x40
158 #define BSSGP_PDU_STATUS 0x41
159 #define BSSGP_PDU_DOWNLOAD_BSS_PFC 0x50
160 #define BSSGP_PDU_CREATE_BSS_PFC 0x51
161 #define BSSGP_PDU_CREATE_BSS_PFC_ACK 0x52
162 #define BSSGP_PDU_CREATE_BSS_PFC_NACK 0x53
163 #define BSSGP_PDU_MODIFY_BSS_PFC 0x54
164 #define BSSGP_PDU_MODIFY_BSS_PFC_ACK 0x55
165 #define BSSGP_PDU_DELETE_BSS_PFC 0x56
166 #define BSSGP_PDU_DELETE_BSS_PFC_ACK 0x57
167 #define BSSGP_PDU_DELETE_BSS_PFC_REQ 0x58
168 #define BSSGP_PDU_PERFORM_LOCATION_REQUEST 0x60
169 #define BSSGP_PDU_PERFORM_LOCATION_RESPONSE 0x61
170 #define BSSGP_PDU_PERFORM_LOCATION_ABORT 0x62
171 #define BSSGP_PDU_POSITION_COMMAND 0x63
172 #define BSSGP_PDU_POSITION_RESPONSE 0x64
173 #define BSSGP_PDU_RAN_INFORMATION 0x70
174 #define BSSGP_PDU_RAN_INFORMATION_REQUEST 0x71
175 #define BSSGP_PDU_RAN_INFORMATION_ACK 0x72
176 #define BSSGP_PDU_RAN_INFORMATION_ERROR 0x73
178 static const value_string tab_bssgp_pdu_types[] = {
179 { BSSGP_PDU_DL_UNITDATA, "DL-UNITDATA" },
180 { BSSGP_PDU_UL_UNITDATA, "UL-UNITDATA" },
181 { BSSGP_PDU_RA_CAPABILITY, "RA-CAPABILITY" },
182 { BSSGP_PDU_PTM_UNITDATA, "PTM-UNITDATA" },
183 { BSSGP_PDU_PAGING_PS, "PAGING-PS" },
184 { BSSGP_PDU_PAGING_CS, "PAGING-CS" },
185 { BSSGP_PDU_RA_CAPABILITY_UPDATE, "RA-CAPABILITY-UPDATE" },
186 { BSSGP_PDU_RA_CAPABILITY_UPDATE_ACK, "RA-CAPABILITY-UPDATE-ACK" },
187 { BSSGP_PDU_RADIO_STATUS, "RADIO-STATUS" },
188 { BSSGP_PDU_SUSPEND, "SUSPEND" },
189 { BSSGP_PDU_SUSPEND_ACK, "SUSPEND-ACK" },
190 { BSSGP_PDU_SUSPEND_NACK, "SUSPEND-NACK" },
191 { BSSGP_PDU_RESUME, "RESUME" },
192 { BSSGP_PDU_RESUME_ACK, "RESUME-ACK" },
193 { BSSGP_PDU_RESUME_NACK, "RESUME-NACK" },
194 { BSSGP_PDU_BVC_BLOCK, "BVC-BLOCK" },
195 { BSSGP_PDU_BVC_BLOCK_ACK, "BVC-BLOCK-ACK" },
196 { BSSGP_PDU_BVC_RESET, "BVC-RESET" },
197 { BSSGP_PDU_BVC_RESET_ACK, "BVC-RESET-ACK" },
198 { BSSGP_PDU_BVC_UNBLOCK, "UNBLOCK" },
199 { BSSGP_PDU_BVC_UNBLOCK_ACK, "UNBLOCK-ACK" },
200 { BSSGP_PDU_FLOW_CONTROL_BVC, "FLOW-CONTROL-BVC" },
201 { BSSGP_PDU_FLOW_CONTROL_BVC_ACK, "FLOW-CONTROL-BVC-ACK" },
202 { BSSGP_PDU_FLOW_CONTROL_MS, "FLOW-CONTROL-MS" },
203 { BSSGP_PDU_FLOW_CONTROL_MS_ACK, "FLOW-CONTROL-MS-ACK" },
204 { BSSGP_PDU_FLUSH_LL, "FLUSH-LL" },
205 { BSSGP_PDU_FLUSH_LL_ACK, "FLUSH_LL_ACK" },
206 { BSSGP_PDU_LLC_DISCARDED, "LLC-DISCARDED" },
207 { BSSGP_PDU_FLOW_CONTROL_PFC, "FLOW-CONTROL-PFC" },
208 { BSSGP_PDU_FLOW_CONTROL_PFC_ACK, "FLOW-CONTROL-PFC-ACK" },
209 { BSSGP_PDU_SGSN_INVOKE_TRACE, "SGSN-INVOKE-TRACE" },
210 { BSSGP_PDU_STATUS, "STATUS" },
211 { BSSGP_PDU_DOWNLOAD_BSS_PFC, "DOWNLOAD-BSS-PFC" },
212 { BSSGP_PDU_CREATE_BSS_PFC, "CREATE-BSS-PFC" },
213 { BSSGP_PDU_CREATE_BSS_PFC_ACK, "CREATE-BSS-PFC-ACK" },
214 { BSSGP_PDU_CREATE_BSS_PFC_NACK, "CREATE-BSS-PFC-NACK" },
215 { BSSGP_PDU_MODIFY_BSS_PFC, "MODIFY-BSS-PFC" },
216 { BSSGP_PDU_MODIFY_BSS_PFC_ACK, "MODIFY-BSS-PFC-ACK" },
217 { BSSGP_PDU_DELETE_BSS_PFC, "DELETE-BSS-PFC" },
218 { BSSGP_PDU_DELETE_BSS_PFC_ACK, "DELETE-BSS-PFC-ACK" },
219 { BSSGP_PDU_DELETE_BSS_PFC_REQ, "DELETE-BSS-PFC-REQ" },
220 { BSSGP_PDU_PERFORM_LOCATION_REQUEST, "PERFORM-LOCATION-REQUEST" },
221 { BSSGP_PDU_PERFORM_LOCATION_RESPONSE, "PERFORM-LOCATION-RESPONSE" },
222 { BSSGP_PDU_PERFORM_LOCATION_ABORT, "PERFORM-LOCATION-ABORT" },
223 { BSSGP_PDU_POSITION_COMMAND, "POSITION-COMMAND" },
224 { BSSGP_PDU_POSITION_RESPONSE, "POSITION-RESPONSE" },
225 { BSSGP_PDU_RAN_INFORMATION, "RAN-INFORMATION" },
226 { BSSGP_PDU_RAN_INFORMATION_REQUEST, "RAN-INFORMATION-REQUEST" },
227 { BSSGP_PDU_RAN_INFORMATION_ACK, "RAN-INFORMATION-ACK" },
228 { BSSGP_PDU_RAN_INFORMATION_ERROR, "RAN-INFORMATION-ERROR" },
232 /* Information element coding, v 6.5.0, table 11.3, p 72 */
233 #define BSSGP_IEI_ALIGNMENT_OCTETS 0x00
234 #define BSSGP_IEI_BMAX_DEFAULT_MS 0x01
235 #define BSSGP_IEI_BSS_AREA_INDICATION 0x02
236 #define BSSGP_IEI_BUCKET_LEAK_RATE 0x03
237 #define BSSGP_IEI_BVCI 0x04
238 #define BSSGP_IEI_BVC_BUCKET_SIZE 0x05
239 #define BSSGP_IEI_BVC_MEASUREMENT 0x06
240 #define BSSGP_IEI_CAUSE 0x07
241 #define BSSGP_IEI_CELL_IDENTIFIER 0x08
242 #define BSSGP_IEI_CHANNEL_NEEDED 0x09
243 #define BSSGP_IEI_DRX_PARAMETERS 0x0a
244 #define BSSGP_IEI_EMLPP_PRIORITY 0x0b
245 #define BSSGP_IEI_FLUSH_ACTION 0x0c
246 #define BSSGP_IEI_IMSI 0x0d
247 #define BSSGP_IEI_LLC_PDU 0x0e
248 #define BSSGP_IEI_LLC_FRAMES_DISCARDED 0x0f
249 #define BSSGP_IEI_LOCATION_AREA 0x10
250 #define BSSGP_IEI_MOBILE_ID 0x11
251 #define BSSGP_IEI_MS_BUCKET_SIZE 0x12
252 #define BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY 0x13
253 #define BSSGP_IEI_OMC_ID 0x14
254 #define BSSGP_IEI_PDU_IN_ERROR 0x15
255 #define BSSGP_IEI_PDU_LIFETIME 0x16
256 #define BSSGP_IEI_PRIORITY 0x17
257 #define BSSGP_IEI_QOS_PROFILE 0x18
258 #define BSSGP_IEI_RADIO_CAUSE 0x19
259 #define BSSGP_IEI_RA_CAP_UPD_CAUSE 0x1a
260 #define BSSGP_IEI_ROUTEING_AREA 0x1b
261 #define BSSGP_IEI_R_DEFAULT_MS 0x1c
262 #define BSSGP_IEI_SUSPEND_REFERENCE_NUMBER 0x1d
263 #define BSSGP_IEI_TAG 0x1e
264 #define BSSGP_IEI_TLLI 0x1f
265 #define BSSGP_IEI_TMSI 0x20
266 #define BSSGP_IEI_TRACE_REFERENCE 0x21
267 #define BSSGP_IEI_TRACE_TYPE 0x22
268 #define BSSGP_IEI_TRANSACTION_ID 0x23
269 #define BSSGP_IEI_TRIGGER_ID 0x24
270 #define BSSGP_IEI_NUMBER_OF_OCTETS_AFFECTED 0x25
271 #define BSSGP_IEI_LSA_IDENTIFIER_LIST 0x26
272 #define BSSGP_IEI_LSA_INFORMATION 0x27
273 #define BSSGP_IEI_PFI 0x28
274 #define BSSGP_IEI_GPRS_TIMER 0x29
275 #define BSSGP_IEI_ABQP 0x3a
276 #define BSSGP_IEI_FEATURE_BITMAP 0x3b
277 #define BSSGP_IEI_BUCKET_FULL_RATIO 0x3c
278 #define BSSGP_IEI_SERVICE_UTRAN_CCO 0x3d
279 #define BSSGP_IEI_NSEI 0x3e
280 #define BSSGP_IEI_RRLP_APDU 0x3f
281 #define BSSGP_IEI_LCS_QOS 0x40
282 #define BSSGP_IEI_LCS_CLIENT_TYPE 0x41
283 #define BSSGP_IEI_REQUESTED_GPS_ASSISTANCE_DATA 0x42
284 #define BSSGP_IEI_LOCATION_TYPE 0x43
285 #define BSSGP_IEI_LOCATION_ESTIMATE 0x44
286 #define BSSGP_IEI_POSITIONING_DATA 0x45
287 #define BSSGP_IEI_DECIPHERING_KEYS 0x46
288 #define BSSGP_IEI_LCS_PRIORITY 0x47
289 #define BSSGP_IEI_LCS_CAUSE 0x48
290 #define BSSGP_IEI_LCS_CAPABILITY 0x49
291 #define BSSGP_IEI_RRLP_FLAGS 0x4a
292 #define BSSGP_IEI_RIM_APPLICATION_IDENTITY 0x4b
293 #define BSSGP_IEI_RIM_SEQUENCE_NUMBER 0x4c
294 #define BSSGP_IEI_RAN_INFORMATION_REQUEST_CONTAINER_UNIT 0x4d
295 #define BSSGP_IEI_RAN_INFORMATION_CONTAINER_UNIT 0x4e
296 #define BSSGP_IEI_RAN_INFORMATION_INDICATIONS 0x4f
297 #define BSSGP_IEI_NUMBER_OF_CONTAINER_UNITS 0x50
298 #define BSSGP_IEI_PFC_FLOW_CONTROL_PARAMETERS 0x52
299 #define BSSGP_IEI_GLOBAL_CN_ID 0x53
301 static const value_string tab_bssgp_ie_types[] = {
302 { BSSGP_IEI_ALIGNMENT_OCTETS, "Alignment Octets" },
303 { BSSGP_IEI_BMAX_DEFAULT_MS, "Bmax Default MS" },
304 { BSSGP_IEI_BSS_AREA_INDICATION, "BSS Area Indication" },
305 { BSSGP_IEI_BUCKET_LEAK_RATE, "Bucket Leak Rate" },
306 { BSSGP_IEI_BVCI, "BVCI" },
307 { BSSGP_IEI_BVC_BUCKET_SIZE, "BVC Bucket Size" },
308 { BSSGP_IEI_BVC_MEASUREMENT, "BVC Measurement" },
309 { BSSGP_IEI_CAUSE, "Cause" },
310 { BSSGP_IEI_CELL_IDENTIFIER, "Cell Identifier" },
311 { BSSGP_IEI_CHANNEL_NEEDED, "Channel Needed" },
312 { BSSGP_IEI_DRX_PARAMETERS, "DRX Parameters" },
313 { BSSGP_IEI_EMLPP_PRIORITY, "eMLPP Priority" },
314 { BSSGP_IEI_FLUSH_ACTION, "Flush Action" },
315 { BSSGP_IEI_IMSI, "IMSI" },
316 { BSSGP_IEI_LLC_PDU, "LLC PDU" },
317 { BSSGP_IEI_LLC_FRAMES_DISCARDED, "LLC Frames Discarded" },
318 { BSSGP_IEI_LOCATION_AREA, "Location Area" },
319 { BSSGP_IEI_MOBILE_ID, "Mobile Id" },
320 { BSSGP_IEI_MS_BUCKET_SIZE, "MS Bucket Size" },
321 { BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY, "MS Radio Access Capability" },
322 { BSSGP_IEI_OMC_ID, "OMC Id" },
323 { BSSGP_IEI_PDU_IN_ERROR, "PDU In Error" },
324 { BSSGP_IEI_PDU_LIFETIME, "PDU Lifetime" },
325 { BSSGP_IEI_PRIORITY, "Priority" },
326 { BSSGP_IEI_QOS_PROFILE, "QoS Profile" },
327 { BSSGP_IEI_RADIO_CAUSE, "Radio Cause" },
328 { BSSGP_IEI_RA_CAP_UPD_CAUSE, "RA-Cap-UPD-Cause" },
329 { BSSGP_IEI_ROUTEING_AREA, "Routeing Area" },
330 { BSSGP_IEI_R_DEFAULT_MS, "R_default_MS" },
331 { BSSGP_IEI_SUSPEND_REFERENCE_NUMBER, "Suspend Reference Number" },
332 { BSSGP_IEI_TAG, "Tag" },
333 { BSSGP_IEI_TLLI, "TLLI" },
334 { BSSGP_IEI_TMSI, "TMSI" },
335 { BSSGP_IEI_TRACE_REFERENCE, "Trace Reference" },
336 { BSSGP_IEI_TRACE_TYPE, "Trace Type" },
337 { BSSGP_IEI_TRANSACTION_ID, "Transaction Id" },
338 { BSSGP_IEI_TRIGGER_ID, "Trigger Id" },
339 { BSSGP_IEI_NUMBER_OF_OCTETS_AFFECTED, "Number of Octets Affected" },
340 { BSSGP_IEI_LSA_IDENTIFIER_LIST, "LSA Identifier List" },
341 { BSSGP_IEI_LSA_INFORMATION, "LSA Information" },
342 { BSSGP_IEI_PFI, "Packet Flow Identiifer" },
343 { BSSGP_IEI_GPRS_TIMER, "GPRS Timer" },
344 { BSSGP_IEI_ABQP, "ABQP" },
345 { BSSGP_IEI_FEATURE_BITMAP, "Feature Bitmap" },
346 { BSSGP_IEI_BUCKET_FULL_RATIO, "Bucket Full Ratio" },
347 { BSSGP_IEI_SERVICE_UTRAN_CCO, "Service UTRAN CCO" },
348 { BSSGP_IEI_NSEI, "NSEI" },
349 { BSSGP_IEI_RRLP_APDU, "RRLP APDU" },
350 { BSSGP_IEI_LCS_QOS, "LCS QoS" },
351 { BSSGP_IEI_LCS_CLIENT_TYPE, "LCS Client Type" },
352 { BSSGP_IEI_REQUESTED_GPS_ASSISTANCE_DATA, "Requested GPS Assistance Data" },
353 { BSSGP_IEI_LOCATION_TYPE, "Location Type" },
354 { BSSGP_IEI_LOCATION_ESTIMATE, "Location Estimate" },
355 { BSSGP_IEI_POSITIONING_DATA, "Positioning Data" },
356 { BSSGP_IEI_DECIPHERING_KEYS, "Deciphering Keys" },
357 { BSSGP_IEI_LCS_PRIORITY, "LCS Priority" },
358 { BSSGP_IEI_LCS_CAUSE, "LCS Cause" },
359 { BSSGP_IEI_LCS_CAPABILITY, "LCS Capability" },
360 { BSSGP_IEI_RRLP_FLAGS, "RRLP Flags" },
361 { BSSGP_IEI_RIM_APPLICATION_IDENTITY, "RIM Application Identity" },
362 { BSSGP_IEI_RIM_SEQUENCE_NUMBER, "RIM Sequence Number" },
363 { BSSGP_IEI_RAN_INFORMATION_REQUEST_CONTAINER_UNIT, "RAN INFORMATION REQUEST Container Unit" },
364 { BSSGP_IEI_RAN_INFORMATION_CONTAINER_UNIT, "RAN INFORMATION Container Unit" },
365 { BSSGP_IEI_RAN_INFORMATION_INDICATIONS, "RAN INFORMATION Indications" },
366 { BSSGP_IEI_NUMBER_OF_CONTAINER_UNITS, "Number of Container Units" },
367 { BSSGP_IEI_PFC_FLOW_CONTROL_PARAMETERS, "PFC Flow Control Parameters" },
368 { BSSGP_IEI_GLOBAL_CN_ID, "Global CN Id" },
372 /* Presence requirements of Information Elements
373 48.016 v 5.3.0, chapter 8.1.1, p. 35 */
374 #define BSSGP_IE_PRESENCE_M 1 /* Mandatory */
375 #define BSSGP_IE_PRESENCE_O 2 /* Conditional */
376 #define BSSGP_IE_PRESENCE_C 3 /* Optional */
379 #define BSSGP_IE_FORMAT_V 1
380 #define BSSGP_IE_FORMAT_TV 2
381 #define BSSGP_IE_FORMAT_TLV 3
388 gint16 value_length; /* in bytes (read from capture)*/
389 gint16 total_length; /* as specified, or 0 if unspecified */
396 proto_tree *bssgp_tree;
397 proto_tree *parent_tree;
403 get_masked_guint8(guint8 value, guint8 mask) {
404 const guint8 MASK_BIT_1 = 0x01;
407 while (!((mask >> i) & MASK_BIT_1)) {
411 return (value & mask) >> i;
416 get_masked_guint16(guint16 value, guint16 mask) {
417 const guint16 MASK_BIT_1 = 0x01;
420 while (!((mask >> i) & MASK_BIT_1)) {
422 if (i > 15) return 0;
424 return (value & mask) >> i;
429 make_mask32(guint8 num_bits, guint8 shift_value) {
430 const guint32 LEFT_MOST_1 = 0x80000000;
432 guint32 mask = LEFT_MOST_1;
434 for (i = 0; i < (num_bits - 1); i++) {
435 mask = (mask >> 1) | LEFT_MOST_1;
437 return mask >> shift_value;
441 get_masked_guint32(guint32 value, guint32 mask) {
442 const guint16 MASK_BIT_1 = 0x01;
445 while (!((mask >> i) & MASK_BIT_1)) {
447 if (i > 31) return 0;
449 return (value & mask) >> i;
453 tvb_get_masked_guint8(tvbuff_t *tvb, int offset, guint8 mask) {
454 guint8 value = tvb_get_guint8(tvb, offset);
455 return get_masked_guint8(value, mask);
459 get_bit_field_label(guint16 value, guint16 value_mask, guint16 num_bits) {
460 #define MAX_NUM_BITS 16
462 static char label[MAX_NUM_BITS + 1];
464 DISSECTOR_ASSERT(num_bits <= MAX_NUM_BITS);
465 for (i = 0; i < num_bits; i++) {
467 if (value_mask & bit_mask) {
468 label[num_bits - 1 - i] = (value & bit_mask) ? '1' : '0';
471 label[num_bits - 1 - i] = '.';
479 get_bit_field_label8(guint8 value, guint8 value_mask) {
481 static char formatted_label[10];
482 bits = get_bit_field_label(value, value_mask, 8);
483 g_snprintf(formatted_label, 10, "%c%c%c%c %c%c%c%c",
484 bits[0], bits[1], bits[2], bits[3],
485 bits[4], bits[5], bits[6], bits[7]);
486 return formatted_label;
490 get_bit_field_label16(guint16 value, guint16 value_mask) {
492 static char formatted_label[18];
493 bits = get_bit_field_label(value, value_mask, 16);
494 g_snprintf(formatted_label, 18, "%c%c%c%c%c%c%c%c %c%c%c%c%c%c%c%c",
495 bits[0], bits[1], bits[2], bits[3],
496 bits[4], bits[5], bits[6], bits[7],
497 bits[8], bits[9], bits[10], bits[11],
498 bits[12], bits[13], bits[14], bits[15]);
499 return formatted_label;
503 proto_tree_add_bitfield8(proto_tree *tree, tvbuff_t *tvb, int offset, guint8 mask) {
504 /* XXX: Use varargs */
505 guint8 value = tvb_get_guint8(tvb, offset);
506 char *label = get_bit_field_label8(value, mask);
507 proto_item *pi = proto_tree_add_text(tree, tvb, offset, 1, "%s = ",
514 proto_tree_add_bitfield16(proto_tree *tree, tvbuff_t *tvb, int offset, guint16 mask) {
515 /* XXX: Use varargs */
516 guint16 value = tvb_get_ntohs(tvb, offset);
517 char *label = get_bit_field_label16(value, mask);
518 proto_item *pi = proto_tree_add_text(tree, tvb, offset, 2, "%s = ",
525 get_byte_offset(guint64 bo) {
526 return (guint8) bo % 8;
530 get_start_octet(guint64 bo) {
531 return (guint32) floor((gint64)bo / 8.0);
535 get_end_octet(guint64 bo, guint32 bl)
537 return (guint32) ceil((gint64)(bo + bl) / 8.0);
541 get_num_octets_spanned(guint64 bo, guint32 bl)
543 return get_end_octet(bo, bl) - get_start_octet(bo);
547 make_mask(guint8 num_bits, guint8 shift_value) {
551 case 0: mask = 0x0000; break;
552 case 1: mask = 0x8000; break;
553 case 2: mask = 0xc000; break;
554 case 3: mask = 0xe000; break;
555 case 4: mask = 0xf000; break;
556 case 5: mask = 0xf800; break;
557 case 6: mask = 0xfc00; break;
558 case 7: mask = 0xfe00; break;
559 case 8: mask = 0xff00; break;
560 default: DISSECTOR_ASSERT_NOT_REACHED(); mask = 0; break;
562 return mask >> shift_value;
566 tvb_get_bits8(tvbuff_t *tvb, guint64 bo, guint8 num_bits) {
567 /* Returns 0-8 bits from tvb */
571 shift_value = get_byte_offset(bo);
572 mask = make_mask(num_bits, shift_value);
573 data = tvb_get_ntohs(tvb, get_start_octet(bo));
574 return (data & mask) >> (16 - shift_value - num_bits);
578 bit_proto_tree_add_text(proto_tree *tree, tvbuff_t *tvb,
579 guint64 bo, guint8 bl, const char *value) {
580 /* XXX: Use varargs */
581 return proto_tree_add_text(tree, tvb, get_start_octet(bo),
582 get_num_octets_spanned(bo, bl), value);
586 bit_proto_tree_add_bit_field8(proto_tree *tree, tvbuff_t *tvb,
587 guint64 bo, guint8 bl) {
588 /* XXX: Use varargs */
589 guint16 value = tvb_get_ntohs(tvb, get_start_octet(bo));
590 guint16 mask = make_mask(bl, get_byte_offset(bo));
591 char *label = get_bit_field_label16(value, mask);
596 DISSECTOR_ASSERT(bl < 9);
598 if (get_num_octets_spanned(bo, bl) == 1) {
604 pi = bit_proto_tree_add_text(tree, tvb, bo, bl, "");
606 for (i = 0; i <=end_i; i++) {
607 proto_item_append_text(pi, "%c", label[i]);
609 proto_item_append_text(pi, " = ");
614 translate_abqp_reliability_class(guint8 value, build_info_t *bi) {
618 return "Subscribed reliability class";
624 return "Unused (Unacknowledged GTP; Acknowledged LLc and RLC, Protected data)";
626 return "Unacknowledged GTP; Acknowledged LLc and RLC, Protected data";
628 return "Unacknowledged GTP and LLC; Acknowledged RLC, Protected data";
630 return "Unacknowledged GTP, LLC, and RLC, Protected data";
632 return "Unacknowledged GTP, LLC, and RLC, Unprotedcted data";
636 return "Unacknowledged GTP and LLC; Acknowledged RLC, Protected data";
640 translate_abqp_delay_class(guint8 value, build_info_t *bi) {
644 return "Subscribed delay class";
649 case 1: return "Delay class 1";
650 case 2: return "Delay class 2";
651 case 3: return "Delay class 3";
652 case 4: return "Delay class 4 (best effort)";
653 case 7: return "Reserved";
655 return "Delay class 4 (best effort)";
659 translate_abqp_peak_throughput(guint8 value, build_info_t *bi) {
663 return "Subscribed peak throughput";
668 case 1: return "Up to 1 000 octets/s";
669 case 2: return "Up to 2 000 octets/s";
670 case 3: return "Up to 4 000 octets/s";
671 case 4: return "Up to 8 000 octets/s";
672 case 5: return "Up to 16 000 octets/s";
673 case 6: return "Up to 32 000 octets/s";
674 case 7: return "Up to 64 000 octets/s";
675 case 8: return "Up to 128 000 octets/s";
676 case 9: return "Up to 256 000 octets/s";
677 case 15: return "Reserved";
679 return "Up to 1 000 octets/s";
683 translate_abqp_precedence_class(guint8 value, build_info_t *bi) {
687 return "Subscribed precedence";
692 case 1: return "High priority";
693 case 2: return "Normal priority";
694 case 3: return "Low priority";
695 case 7: return "Reserved";
697 return "Normal priority";
701 translate_abqp_mean_throughput(guint8 value, build_info_t *bi) {
705 return "Subscribed mean throughput";
710 case 1: return "100 octets/h";
711 case 2: return "200 octets/h";
712 case 3: return "500 octets/h";
713 case 4: return "1 000 octets/h";
714 case 5: return "2 000 octets/h";
715 case 6: return "5 000 octets/h";
716 case 7: return "10 000 octets/h";
717 case 8: return "20 000 octets/h";
718 case 9: return "50 000 octets/h";
719 case 0x0a: return "100 000 octets/h";
720 case 0x0b: return "200 000 octets/h";
721 case 0x0c: return "500 000 octets/h";
722 case 0x0d: return "1 000 000 octets/h";
723 case 0x0e: return "2 000 000 octets/h";
724 case 0x0f: return "5 000 000 octets/h";
725 case 0x10: return "10 000 000 octets/h";
726 case 0x11: return "20 000 000 octets/h";
727 case 0x12: return "50 000 000 octets/h";
728 case 0x1e: return "Reserved";
729 case 0x1f: return "Best effort";
731 return "Best effort";
735 translate_abqp_traffic_class(guint8 value, build_info_t *bi) {
739 return "Subscribed traffic class";
744 case 1: return "Conversational class";
745 case 2: return "Streaming class";
746 case 3: return "Interactive class";
747 case 4: return "Background class";
748 case 7: return "Reserved";
751 /* The MS shall consider all other values as reserved */
755 /* 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 */
761 translate_abqp_delivery_order(guint8 value, build_info_t *bi) {
765 return "Subscribed delivery order";
770 case 1: return "With delivery order ('yes')";
771 case 2: return "Without delivery order ('no')";
772 case 3: return "Reserved";
774 return "Error in BSSGP dissector";
778 translate_abqp_delivery_of_erroneous_sdu(guint8 value, build_info_t *bi) {
782 return "Subscribed delivery of erroneous SDUs";
787 case 1: return "No detect ('-')";
788 case 2: return "Erroneous SDUs are delivered ('yes')";
789 case 3: return "Erroneous SDUs are not delivered ('no')";
790 case 7: return "Reserved";
793 /* The MS shall consider all other values as reserved */
797 /* 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 */
803 translate_abqp_max_sdu_size(guint8 value, build_info_t *bi) {
804 static char result[BSSGP_TRANSLATION_MAX_LEN];
809 return "Subscribed maximum SDU size";
821 case 0x97: return "1502 octets";
822 case 0x98: return "1510 octets";
823 case 0x99: return "1520 octets";
825 if ((value >= 1) && (value <= 0x96)) {
826 g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u octets", value * 10);
830 /* The MS shall consider all other values as reserved */
834 /* 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 */
840 translate_abqp_max_bit_rate_for_ul(guint8 value, build_info_t *bi) {
841 static char result[BSSGP_TRANSLATION_MAX_LEN];
845 return "Subscribed maximum bit rate for uplink";
851 if ((value >= 1) && (value <= 0x3f)) {
852 g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u kbps", value);
855 if ((value >= 0x40) && (value <= 0x7f)) {
856 g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u kbps", 64 + (value - 0x40) * 8);
859 if ((value >= 0x80) && (value <= 0xfe)) {
860 g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u kbps", 576 + (value - 0x80) * 64);
867 translate_abqp_max_bit_rate_for_dl(guint8 value, build_info_t *bi) {
868 return translate_abqp_max_bit_rate_for_ul(value, bi);
872 translate_abqp_residual_ber(guint8 value, build_info_t *bi) {
876 return "Subscribed residual BER";
881 case 1: return "5*10^-2";
882 case 2: return "1*10^-2";
883 case 3: return "5*10^-3";
884 case 4: return "4*10^-3";
885 case 5: return "1*10^-3";
886 case 6: return "1*10^-4";
887 case 7: return "1*10^-5";
888 case 8: return "1*10^-6";
889 case 9: return "6*10^-8";
890 case 15: return "Reserved";
893 /* The MS shall consider all other values as reserved */
897 /* 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 */
903 translate_abqp_sdu_error_ratio(guint8 value, build_info_t *bi) {
907 return "Subscribed SDU error ratio";
912 case 1: return "1*10^-2";
913 case 2: return "7*10^-3";
914 case 3: return "1*10^-3";
915 case 4: return "1*10^-4";
916 case 5: return "1*10^-5";
917 case 6: return "1*10^-6";
918 case 7: return "1*10^-1";
919 case 15: return "Reserved";
922 /* The MS shall consider all other values as reserved */
926 /* 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 */
932 translate_abqp_transfer_delay(guint8 value, build_info_t *bi) {
933 static char result[BSSGP_TRANSLATION_MAX_LEN];
937 return "Subscribed transfer delay";
943 if ((value >= 1) && (value <= 0x0f)) {
944 g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u ms", value * 10);
947 if ((value >= 0x10) && (value <= 0x1f)) {
948 g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u ms", 200 + (value - 0x10) * 50);
951 if ((value >= 0x20) && (value <= 0x3e)) {
952 g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u ms", 1000 + (value - 0x20) * 100);
959 translate_abqp_traffic_handling_priority(guint8 value, build_info_t *bi) {
963 return "Subscribed traffic handling_priority";
968 case 1: return "Priority level 1";
969 case 2: return "Priority level 2";
970 case 3: return "Priority level 3";
976 translate_abqp_guaranteed_bit_rate_for_ul(guint8 value, build_info_t *bi) {
977 return translate_abqp_max_bit_rate_for_ul(value, bi);
980 translate_abqp_guaranteed_bit_rate_for_dl(guint8 value, build_info_t *bi) {
981 return translate_abqp_max_bit_rate_for_ul(value, bi);
985 translate_abqp_source_statistics_descriptor(guint8 value, build_info_t *bi) {
988 case 0: return "Unknown";
989 case 1: return "Speech";
990 default: return "Unknown";
999 translate_abqp_max_bit_rate_for_dl_extended(guint8 value, build_info_t *bi _U_) {
1000 static char result[BSSGP_TRANSLATION_MAX_LEN];
1003 return "Use the value indicated by the Maximum bit rate for downlink";
1005 if ((value >= 1) || (value <= 0x4a)) {
1006 g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u kbps", 8600 + value * 100);
1009 /* 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 */
1014 translate_abqp_guaranteed_bit_rate_for_dl_extended(guint8 value, build_info_t *bi _U_) {
1015 static char result[BSSGP_TRANSLATION_MAX_LEN];
1018 return "Use the value indicated by the Guaranteed bit rate for downlink";
1020 if ((value >= 1) || (value <= 0x4a)) {
1021 g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u kbps", 8600 + value * 100);
1024 /* 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 */
1029 translate_msrac_access_technology_type(guint8 value) {
1030 static const value_string tab_values[] = {
1041 { 10, "GSM T 410" },
1042 { 11, "GSM T 900" },
1043 { 15, "List of Additional Access Technologies present" },
1045 /* Otherwise "Unknown" */
1047 return val_to_str(value, tab_values, "Unknown");
1051 translate_msrac_dtm_gprs_multislot_class(guint8 value) {
1052 static const value_string tab_values[] = {
1053 { 0, "Unused, interpreted as \"Multislot class 5 supported\"" },
1054 { 1, "Multislot class 5 supported" },
1055 { 2, "Multislot class 9 supported" },
1056 { 3, "Multislot class 11 supported" },
1058 /* No other combinations*/
1060 return val_to_str(value, tab_values, "");
1064 translate_msrac_extended_dtm_gprs_multislot_class(guint8 value, guint8 dgmsc) {
1066 case 0: return "Unused, interpreted as Multislot class 5 supported";
1069 case 0: return "Multislot class 5 supported";
1070 case 1: return "Multislot class 6 supported";
1073 return "Unused, interpreted as Multislot class 5 supported";
1077 case 0: return "Multislot class 9 supported";
1078 case 1: return "Multislot class 10 supported";
1081 return "Unused, interpreted as Multislot class 5 supported";
1085 case 0: return "Multislot class 11 supported";
1089 return "Unused, interpreted as Multislot class 5 supported";
1092 DISSECTOR_ASSERT_NOT_REACHED();
1093 return "Error"; /* Dummy */
1098 translate_msrac_high_multislot_capability(guint8 capability, guint8 class) {
1099 switch (capability) {
1189 DISSECTOR_ASSERT_NOT_REACHED();
1195 translate_channel_needed(guint8 value) {
1197 case 0: return "Any channel";
1198 case 1: return "SDCCH";
1199 case 2: return "TCH/F (Full rate)";
1200 case 3: return "TCH/H or TCH/F (Dual rate)";
1202 DISSECTOR_ASSERT_NOT_REACHED();
1207 bssgp_proto_tree_add_ie(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1208 return proto_tree_add_uint_format(bi->bssgp_tree, hf_bssgp_ie_type,
1209 bi->tvb, ie_start_offset, ie->total_length,
1214 bssgp_proto_handoff(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset, dissector_handle_t handle) {
1217 next_tvb = tvb_new_subset(bi->tvb, bi->offset, -1, -1);
1219 if (bi->bssgp_tree) {
1220 bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1223 call_dissector(handle, next_tvb, bi->pinfo, bi->parent_tree);
1225 else if (data_handle) {
1226 call_dissector(data_handle, next_tvb, bi->pinfo, bi->parent_tree);
1231 decode_nri(proto_tree *tf, build_info_t *bi, guint32 tmsi_tlli) {
1232 const guint32 LOCAL_TLLI_MASK = 0xc0000000;
1233 const guint32 FOREIGN_TLLI_MASK = 0x80000000;
1236 if (bssgp_decode_nri && (bssgp_nri_length != 0) &&
1237 (((tmsi_tlli & LOCAL_TLLI_MASK) == LOCAL_TLLI_MASK) ||
1238 ((tmsi_tlli & FOREIGN_TLLI_MASK) == FOREIGN_TLLI_MASK))) {
1239 nri = get_masked_guint32(tmsi_tlli, make_mask32( (guint8) bssgp_nri_length, 8));
1241 proto_tree_add_uint_hidden(tf, hf_bssgp_nri, bi->tvb, bi->offset, 4,
1244 if (check_col(bi->pinfo->cinfo, COL_INFO)) {
1245 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP,
1252 decode_mobile_identity(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1253 #define MAX_NUM_IMSI_DIGITS 15
1254 const guint8 MASK_ODD_EVEN_INDICATION = 0x08;
1255 const guint8 MASK_TYPE_OF_IDENTITY = 0x07;
1256 const guint8 ODD = 1;
1257 proto_item *ti = NULL, *pi;
1258 proto_tree *tf = NULL;
1259 guint8 data, odd_even, type, num_digits, i;
1262 guint8 digits[MAX_NUM_IMSI_DIGITS];
1263 char digits_str[MAX_NUM_IMSI_DIGITS + 1];
1265 static const value_string tab_type_of_identity[] = {
1266 { BSSGP_MOBILE_IDENTITY_TYPE_IMSI, "IMSI" },
1267 { BSSGP_MOBILE_IDENTITY_TYPE_IMEI, "IMEI" },
1268 { BSSGP_MOBILE_IDENTITY_TYPE_IMEISV, "IMEISV" },
1269 { BSSGP_MOBILE_IDENTITY_TYPE_TMSI_PTMSI, "TMSI//P-TMSI" },
1270 { BSSGP_MOBILE_IDENTITY_TYPE_NO_IDENTITY, "No identity" },
1272 /* Otherwise "Reserved" */
1275 digits_str[0] = '\0'; /* conceivably num_digits below could be zero */
1277 if (bi->bssgp_tree) {
1278 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1279 tf = proto_item_add_subtree(ti, ett_bssgp_mobile_identity);
1281 data = tvb_get_guint8(bi->tvb, bi->offset);
1282 odd_even = get_masked_guint8(data, MASK_ODD_EVEN_INDICATION);
1284 if (bi->bssgp_tree) {
1285 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
1286 MASK_ODD_EVEN_INDICATION);
1287 proto_item_append_text(pi, "Odd/Even Indication: %s number of identity digits%s",
1288 odd_even == ODD ? "Odd" : "Even",
1289 odd_even == ODD ? "" : " and also when the TMSI/P_TMSI is used");
1291 type = get_masked_guint8(data, MASK_TYPE_OF_IDENTITY);
1293 if (bi->bssgp_tree) {
1294 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
1295 MASK_TYPE_OF_IDENTITY);
1296 proto_item_append_text(pi, "Type of Identity: %s",
1297 val_to_str(type, tab_type_of_identity,
1302 case BSSGP_MOBILE_IDENTITY_TYPE_IMSI:
1303 case BSSGP_MOBILE_IDENTITY_TYPE_IMEI:
1304 case BSSGP_MOBILE_IDENTITY_TYPE_IMEISV:
1305 num_digits = 1 + (ie->value_length - 1) * 2;
1306 if (odd_even != ODD ) num_digits--;
1307 if (num_digits > MAX_NUM_IMSI_DIGITS) THROW(ReportedBoundsError);
1310 digits[i] = get_masked_guint8(data, BSSGP_MASK_LEFT_OCTET_HALF);
1314 data = tvb_get_guint8(bi->tvb, bi->offset);
1316 digits[i] = get_masked_guint8(data, BSSGP_MASK_RIGHT_OCTET_HALF);
1318 if (i >= num_digits) break;
1320 digits[i] = get_masked_guint8(data, BSSGP_MASK_LEFT_OCTET_HALF);
1322 if (i >= num_digits) break;
1327 if (bi->bssgp_tree) {
1328 proto_item_append_text(ti, ": ");
1329 for (i = 0; i < num_digits; i++) {
1330 proto_item_append_text(ti, "%u", digits[i]);
1331 g_snprintf(&digits_str[i], 2, "%u", digits[i]);
1334 case BSSGP_MOBILE_IDENTITY_TYPE_IMSI:
1335 hf_id = hf_bssgp_imsi;
1337 case BSSGP_MOBILE_IDENTITY_TYPE_IMEI:
1338 hf_id = hf_bssgp_imei;
1340 case BSSGP_MOBILE_IDENTITY_TYPE_IMEISV:
1341 hf_id = hf_bssgp_imeisv;
1344 DISSECTOR_ASSERT_NOT_REACHED();
1349 proto_tree_add_string(tf, hf_id, bi->tvb, ie_start_offset + 2, ((num_digits/2)+1), digits_str);
1352 if (check_col(bi->pinfo->cinfo, COL_INFO)) {
1353 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP, "%s %s",
1354 val_to_str(type, tab_type_of_identity,
1355 "Mobile identity unknown"),
1359 case BSSGP_MOBILE_IDENTITY_TYPE_TMSI_PTMSI:
1360 tmsi = tvb_get_ntohl(bi->tvb, bi->offset);
1361 if (check_col(bi->pinfo->cinfo, COL_INFO)) {
1362 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP,
1363 "TMSI/P-TMSI %0x04x", tmsi);
1365 if (bi->bssgp_tree) {
1366 proto_tree_add_item(tf, hf_bssgp_tmsi_ptmsi, bi->tvb, bi->offset, 4,
1367 BSSGP_LITTLE_ENDIAN);
1368 proto_item_append_text(ti, ": %#04x", tmsi);
1370 decode_nri(tf, bi, tmsi);
1376 #undef MAX_NUM_IMSI_DIGITS
1380 decode_mcc_mnc(build_info_t *bi, proto_tree *parent_tree) {
1382 const guint8 UNUSED_MNC3 = 0x0f;
1383 proto_item *pi_mcc, *pi_mnc;
1384 guint8 mcc1, mcc2, mcc3, mnc1, mnc2, mnc3, data;
1385 guint16 start_offset, mcc, mnc;
1386 static char mcc_mnc[RES_LEN];
1388 start_offset = bi->offset;
1390 pi_mcc = proto_tree_add_text(parent_tree, bi->tvb, bi->offset, 3, "MCC");
1391 pi_mnc = proto_tree_add_text(parent_tree, bi->tvb, bi->offset, 3, "MNC");
1393 data = tvb_get_guint8(bi->tvb, bi->offset);
1394 mcc2 = get_masked_guint8(data, BSSGP_MASK_LEFT_OCTET_HALF);
1395 mcc1 = get_masked_guint8(data, BSSGP_MASK_RIGHT_OCTET_HALF);
1398 data = tvb_get_guint8(bi->tvb, bi->offset);
1399 mnc3 = get_masked_guint8(data, BSSGP_MASK_LEFT_OCTET_HALF);
1400 mcc3 = get_masked_guint8(data, BSSGP_MASK_RIGHT_OCTET_HALF);
1403 data = tvb_get_guint8(bi->tvb, bi->offset);
1404 mnc2 = get_masked_guint8(data, BSSGP_MASK_LEFT_OCTET_HALF);
1405 mnc1 = get_masked_guint8(data, BSSGP_MASK_RIGHT_OCTET_HALF);
1408 /* XXX: If mxci out of range the ms should transmit the values using full hexademical encoding? */
1410 /* XXX: Interpretation of mcci? */
1411 mcc = 100 * mcc1 + 10 * mcc2 + mcc3;
1413 /* XXX: Interpretation of mnci? */
1414 mnc = 10 * mnc1 + mnc2;
1416 if (mnc3 != UNUSED_MNC3) {
1417 mnc += 10 * mnc + mnc3;
1420 proto_tree_add_uint_hidden(bi->bssgp_tree, hf_bssgp_mcc,
1421 bi->tvb, start_offset, 3, mcc);
1422 proto_tree_add_uint_hidden(bi->bssgp_tree, hf_bssgp_mnc,
1423 bi->tvb, start_offset, 3, mnc);
1425 proto_item_append_text(pi_mcc, ": %03u", mcc);
1427 if (mnc3 != UNUSED_MNC3) {
1428 /* Three digits mnc */
1429 proto_item_append_text(pi_mnc, ": %03u", mnc);
1430 g_snprintf(mcc_mnc, RES_LEN, "%u-%03u", mcc, mnc);
1433 /* Two digits mnc */
1434 proto_item_append_text(pi_mnc, ": %02u", mnc);
1435 g_snprintf(mcc_mnc, RES_LEN, "%u-%02u", mcc, mnc);
1442 decode_lai(build_info_t *bi, proto_tree *parent_tree) {
1446 static char lai[RES_LEN];
1448 mcc_mnc = decode_mcc_mnc(bi, parent_tree);
1450 lac = tvb_get_ntohs(bi->tvb, bi->offset);
1451 proto_tree_add_item(parent_tree, hf_bssgp_lac,
1452 bi->tvb, bi->offset, 2, BSSGP_LITTLE_ENDIAN);
1455 g_snprintf(lai, RES_LEN, "%s-%u", mcc_mnc, lac);
1461 decode_rai(build_info_t *bi, proto_tree *parent_tree) {
1464 static char rai[RES_LEN];
1465 char *lai = decode_lai(bi, parent_tree);
1467 rac = tvb_get_guint8(bi->tvb, bi->offset);
1468 proto_tree_add_item(parent_tree, hf_bssgp_rac, bi->tvb, bi->offset, 1, BSSGP_LITTLE_ENDIAN);
1471 g_snprintf(rai, RES_LEN, "%s-%u", lai, rac);
1477 decode_rai_ci(build_info_t *bi, proto_tree *parent_tree) {
1480 static char rai_ci[RES_LEN];
1483 rai = decode_rai(bi, parent_tree);
1485 ci = tvb_get_ntohs(bi->tvb, bi->offset);
1486 proto_tree_add_item(parent_tree, hf_bssgp_ci,
1487 bi->tvb, bi->offset, 2, BSSGP_LITTLE_ENDIAN);
1490 g_snprintf(rai_ci, RES_LEN, "RAI %s, CI %u", rai, ci);
1496 bssgp_pi_append_queuing_delay(proto_item *pi, tvbuff_t *tvb, int offset) {
1497 const guint16 INFINITE_DELAY = 0xffff;
1498 guint16 value = tvb_get_ntohs(tvb, offset);
1499 if (value == INFINITE_DELAY) {
1500 proto_item_append_text(pi, ": Infinite delay (%#4x)", value);
1503 proto_item_append_text(pi, ": %u centi-seconds delay", value);
1508 bssgp_pi_append_bucket_leak_rate(proto_item *pi, tvbuff_t *tvb, int offset) {
1509 guint16 value = tvb_get_ntohs(tvb, offset);
1510 proto_item_append_text(pi, ": %u bytes", value * 100);
1514 bssgp_pi_append_bucket_size(proto_item *pi, tvbuff_t *tvb, int offset) {
1515 guint16 value = tvb_get_ntohs(tvb, offset);
1516 proto_item_append_text(pi, ": %u bytes", value * 100);
1520 bssgp_pi_append_bucket_full_ratio(proto_item *pi, tvbuff_t *tvb, int offset) {
1521 guint8 value = tvb_get_guint8(tvb, offset);
1522 proto_item_append_text(pi, ": %.2f * Bmax ", value / 100.0);
1526 bssgp_pi_append_pfi(proto_item *pi, tvbuff_t *tvb, int offset) {
1527 const guint8 MASK_PFI = 0x7f;
1530 static const value_string tab_pfi[] = {
1531 { 0, "Best effort" },
1540 /* Otherwise "Dynamically assigned */
1542 value = tvb_get_masked_guint8(tvb, offset, MASK_PFI);
1543 proto_item_append_text(pi,
1544 val_to_str(value, tab_pfi, "Dynamically assigned"));
1548 decode_pfi(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1550 if (bi->bssgp_tree) {
1551 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1552 bssgp_pi_append_pfi(ti, bi->tvb, bi->offset);
1554 bi->offset += ie->value_length;
1558 decode_queuing_delay(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1560 if (bi->bssgp_tree) {
1561 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1562 bssgp_pi_append_queuing_delay(ti, bi->tvb, bi->offset);
1564 bi->offset += ie->value_length;
1568 decode_bucket_size(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1570 if (bi->bssgp_tree) {
1571 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1572 bssgp_pi_append_bucket_size(ti, bi->tvb, bi->offset);
1574 bi->offset += ie->value_length;
1578 decode_bucket_leak_rate(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1580 if (bi->bssgp_tree) {
1581 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1582 bssgp_pi_append_bucket_leak_rate(ti, bi->tvb, bi->offset);
1584 bi->offset += ie->value_length;
1588 get_value_length(bssgp_ie_t *ie, build_info_t *bi) {
1589 /* length indicator in bit 8, 0 => two bytes, 1 => one byte */
1590 const guint8 MASK_LENGTH_INDICATOR = 0x80;
1591 const guint8 MASK_ONE_BYTE_LENGTH = 0x7f;
1595 length = tvb_get_guint8(bi->tvb, bi->offset);
1598 if (length & MASK_LENGTH_INDICATOR) {
1599 length &= MASK_ONE_BYTE_LENGTH;
1604 length |= tvb_get_guint8(bi->tvb, bi->offset);
1606 ie->value_length = length;
1607 ie->total_length += length_len + length;
1608 bi->offset += length_len;
1612 decode_simple_ie(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset,
1613 const char *pre_str, const char *post_str,
1614 gboolean show_as_dec) {
1615 /* XXX: Allow mask? */
1619 switch (ie->value_length) {
1620 case 1: value = tvb_get_guint8(bi->tvb, bi->offset); break;
1621 case 2: value = tvb_get_ntohs(bi->tvb, bi->offset); break;
1622 case 3: value = tvb_get_ntoh24(bi->tvb, bi->offset); break;
1623 case 4: value = tvb_get_ntohl(bi->tvb, bi->offset); break;
1624 default: value = 0; break;
1627 if (bi->bssgp_tree) {
1628 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1630 proto_item_append_text(ti, ": ");
1633 proto_item_append_text(ti, "%s ", pre_str);
1636 proto_item_append_text(ti, "%u", value);
1639 switch (ie->value_length) {
1640 case 1: proto_item_append_text(ti, "%#1x", value); break;
1641 case 2: proto_item_append_text(ti, "%#2x", value); break;
1642 case 3: proto_item_append_text(ti, "%#3x", value); break;
1643 case 4: proto_item_append_text(ti, "%#4x", value); break;
1647 proto_item_append_text(ti, " %s", post_str);
1649 bi->offset += ie->value_length;
1653 check_correct_iei(bssgp_ie_t *ie, build_info_t *bi) {
1654 guint8 fetched_iei = tvb_get_guint8(bi->tvb, bi->offset);
1657 if (fetched_iei != ie->iei) {
1658 proto_tree_add_text(bi->bssgp_tree, bi->tvb, bi->offset, 1,
1659 "Tried IEI %s (%#02x), found IEI %s (%#02x)",
1660 val_to_str(ie->iei, tab_bssgp_ie_types, "Unknown"),
1662 val_to_str(fetched_iei, tab_bssgp_ie_types, "Unknown"),
1666 return (fetched_iei == ie->iei);
1670 decode_iei_alignment_octets(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1672 if (bi->bssgp_tree) {
1673 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1674 proto_item_append_text(ti, " (%u bytes)", ie->value_length);
1676 bi->offset += ie->value_length;
1680 decode_iei_bvci(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1684 bvci = tvb_get_ntohs(bi->tvb, bi->offset);
1686 if (bi->bssgp_tree) {
1687 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1688 proto_item_append_text(ti, ": %u", bvci);
1689 proto_tree_add_item_hidden(bi->bssgp_tree, hf_bssgp_bvci,
1690 bi->tvb, bi->offset, ie->value_length,
1691 BSSGP_LITTLE_ENDIAN);
1693 bi->offset += ie->value_length;
1695 if (check_col(bi->pinfo->cinfo, COL_INFO)) {
1696 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP,
1702 decode_iei_cause(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1706 static const value_string tab_cause[] = {
1707 { 0x00, "Processor overload" },
1708 { 0x01, "Equipment failure" },
1709 { 0x02, "Transit network service failure" },
1710 { 0x03, "Network service transmission capacity modified from zero kbps to greater than zero kbps" },
1711 { 0x04, "Unknown MS" },
1712 { 0x05, "BVCI unknown" },
1713 { 0x06, "Cell traffic congestion" },
1714 { 0x07, "SGSN congestion" },
1715 { 0x08, "O&M intervention" },
1716 { 0x09, "BVCI blocked" },
1717 { 0x0a, "PFC create failure" },
1718 { 0x0b, "PFC preempted" },
1719 { 0x0c, "ABQP no more supported" },
1720 { 0x20, "Semantically incorrect PDU" },
1721 { 0x21, "Invalid mandatory information" },
1722 { 0x22, "Missing mandatory IE" },
1723 { 0x23, "Missing conditional IE" },
1724 { 0x24, "Unexpected conditional IE" },
1725 { 0x25, "Conditional IE error" },
1726 { 0x26, "PDU not compatible with the protocol state" },
1727 { 0x27, "Protocol error - unspecified" },
1728 { 0x28, "PDU not compatible with the feature set" },
1729 { 0x29, "Requested information not available" },
1730 { 0x2a, "Unknown destination address" },
1731 { 0x2b, "Unknown RIM application identity" },
1732 { 0x2c, "Invalid container unit information" },
1733 { 0x2d, "PFC queing" },
1734 { 0x2e, "PFC created successfully" },
1738 if (bi->bssgp_tree) {
1739 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1740 value = tvb_get_guint8(bi->tvb, bi->offset);
1741 proto_item_append_text(ti, ": %s (%#02x)",
1742 val_to_str(value, tab_cause,
1743 "Protocol error - unspecified"),
1746 bi->offset += ie->value_length;
1750 decode_iei_cell_identifier(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1755 if (bi->bssgp_tree) {
1756 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1757 tf = proto_item_add_subtree(ti, ett_bssgp_cell_identifier);
1759 rai_ci = decode_rai_ci(bi, tf);
1760 proto_item_append_text(ti, ": %s", rai_ci);
1762 bi->offset += ie->value_length;
1767 decode_iei_channel_needed(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1768 /* XXX: 'If this IE is used for only one MS, the the first CHANNEL field
1769 is used and the second CHANNEL field is spare.' How know? */
1770 const guint8 MASK_CH1 = 0x03;
1771 const guint8 MASK_CH2 = 0x0c;
1773 guint8 data, ch1, ch2;
1775 if (bi->bssgp_tree) {
1776 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1777 data = tvb_get_guint8(bi->tvb, bi->offset);
1778 ch1 = get_masked_guint8(data, MASK_CH1);
1779 ch2 = get_masked_guint8(data, MASK_CH2);
1780 proto_item_append_text(ti, ": Ch1: %s (%u), Ch2: %s (%u)",
1781 translate_channel_needed(ch1),
1783 translate_channel_needed(ch2),
1786 bi->offset += ie->value_length;
1790 decode_iei_drx_parameters(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1791 const guint8 MASK_CYCLE_LENGTH_COEFFICIENT = 0xf0;
1792 const guint8 MASK_SPLIT_ON_CCCH = 0x08;
1793 const guint8 MASK_NON_DRX_TIMER = 0x07;
1794 proto_item *ti, *pi;
1797 guint16 cycle_value;
1799 static const value_string tab_non_drx_timer[] = {
1800 { 0, "No non-DRX mode after transfer state" },
1801 { 1, "Max. 1 sec non-DRX mode after transfer state" },
1802 { 2, "Max. 2 sec non-DRX mode after transfer state" },
1803 { 3, "Max. 4 sec non-DRX mode after transfer state" },
1804 { 4, "Max. 8 sec non-DRX mode after transfer state" },
1805 { 5, "Max. 16 sec non-DRX mode after transfer state" },
1806 { 6, "Max. 32 sec non-DRX mode after transfer state" },
1807 { 7, "Max. 64 sec non-DRX mode after transfer state" },
1812 static const value_string tab_cycle_length_coefficient[] = {
1813 { 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" },
1814 { 6, "CN Specific DRX cycle length coefficient 6" },
1815 { 7, "CN Specific DRX cycle length coefficient 7" },
1816 { 8, "CN Specific DRX cycle length coefficient 8" },
1817 { 9, "CN Specific DRX cycle length coefficient 9" },
1819 /* Otherwise "CN Specific DRX cycle length coefficient not specified by the MS" */
1822 if (!bi->bssgp_tree) {
1823 bi->offset += ie->value_length;
1826 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1827 tf = proto_item_add_subtree(ti, ett_bssgp_drx_parameters);
1829 value = tvb_get_guint8(bi->tvb, bi->offset);
1830 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
1831 "SPLIT PG CYCLE: code %u", value);
1832 if ((value >= 1) && (value <= 64)) {
1833 cycle_value = value;
1837 case 0: cycle_value = 704; break;
1838 case 65: cycle_value = 71; break;
1839 case 66: cycle_value = 72; break;
1840 case 67: cycle_value = 74; break;
1841 case 68: cycle_value = 75; break;
1842 case 69: cycle_value = 77; break;
1843 case 70: cycle_value = 79; break;
1844 case 71: cycle_value = 80; break;
1845 case 72: cycle_value = 83; break;
1846 case 73: cycle_value = 86; break;
1847 case 74: cycle_value = 88; break;
1848 case 75: cycle_value = 90; break;
1849 case 76: cycle_value = 92; break;
1850 case 77: cycle_value = 96; break;
1851 case 78: cycle_value = 101; break;
1852 case 79: cycle_value = 103; break;
1853 case 80: cycle_value = 107; break;
1854 case 81: cycle_value = 112; break;
1855 case 82: cycle_value = 116; break;
1856 case 83: cycle_value = 118; break;
1857 case 84: cycle_value = 128; break;
1858 case 85: cycle_value = 141; break;
1859 case 86: cycle_value = 144; break;
1860 case 87: cycle_value = 150; break;
1861 case 88: cycle_value = 160; break;
1862 case 89: cycle_value = 171; break;
1863 case 90: cycle_value = 176; break;
1864 case 91: cycle_value = 192; break;
1865 case 92: cycle_value = 214; break;
1866 case 93: cycle_value = 224; break;
1867 case 94: cycle_value = 235; break;
1868 case 95: cycle_value = 256; break;
1869 case 96: cycle_value = 288; break;
1870 case 97: cycle_value = 320; break;
1871 case 98: cycle_value = 352; break;
1875 proto_item_append_text(ti, " => value %u", cycle_value);
1876 if (cycle_value == 704) {
1877 proto_item_append_text(ti, " (equivalent to no DRX)");
1882 data = tvb_get_guint8(bi->tvb, bi->offset);
1884 value = get_masked_guint8(data, MASK_CYCLE_LENGTH_COEFFICIENT);
1885 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
1886 MASK_CYCLE_LENGTH_COEFFICIENT);
1887 proto_item_append_text(pi, "CN specific DRX cycle length coefficient: %s (%#02x)",
1888 val_to_str(value, tab_cycle_length_coefficient,
1889 "Not specified by the MS"),
1892 value = get_masked_guint8(data, MASK_SPLIT_ON_CCCH);
1893 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_SPLIT_ON_CCCH);
1894 proto_item_append_text(pi, "SPLIT on CCCH: Split pg cycle on CCCH is%s supported by the mobile station",
1895 value == 0 ? " not" : "");
1897 value = get_masked_guint8(data, MASK_NON_DRX_TIMER);
1898 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_NON_DRX_TIMER);
1899 proto_item_append_text(pi, "Non-DRX Timer: %s (%#x)",
1900 val_to_str(value, tab_non_drx_timer, ""), value);
1905 decode_iei_emlpp_priority(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1906 const guint8 MASK_CALL_PRIORITY = 0x07;
1910 static const value_string tab_call_priority[] = {
1911 { 0, "No priority applied" },
1912 { 1, "Call priority level 4" },
1913 { 2, "Call priority level 3" },
1914 { 3, "Call priority level 2" },
1915 { 4, "Call priority level 1" },
1916 { 5, "Call priority level 0" },
1917 { 6, "Call priority level B" },
1918 { 7, "Call priority level A" },
1922 if (bi->bssgp_tree) {
1923 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1924 data = tvb_get_guint8(bi->tvb, bi->offset);
1925 value = get_masked_guint8(data, MASK_CALL_PRIORITY);
1926 proto_item_append_text(ti, ": %s",
1927 val_to_str(value, tab_call_priority, ""));
1929 bi->offset += ie->value_length;
1933 decode_iei_flush_action(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1937 static const value_string tab_action_value[] = {
1938 { 0x00, "LLC-PDU(s) deleted" },
1939 { 0x01, "LLC-PDU(s) transferred" },
1941 /* Otherwise "Reserved" */
1944 if (bi->bssgp_tree) {
1945 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1946 value = tvb_get_guint8(bi->tvb, bi->offset);
1947 proto_item_append_text(ti, ": %s (%u)",
1948 val_to_str(value, tab_action_value, "Reserved"),
1952 bi->offset += ie->value_length;
1956 decode_iei_llc_frames_discarded(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1957 decode_simple_ie(ie, bi, ie_start_offset, "", " frames discarded", TRUE);
1961 decode_iei_location_area(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
1966 if (!bi->bssgp_tree) {
1967 bi->offset += ie->value_length;
1970 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
1971 tf = proto_item_add_subtree(ti, ett_bssgp_location_area);
1973 lai = decode_rai(bi, tf);
1974 proto_item_append_text(ti, ": LAI %s", lai);
1978 decode_msrac_additional_access_technologies(proto_tree *tree, tvbuff_t *tvb,
1979 guint64 bo, guint32 length _U_) {
1982 guint8 bl; /* Bit length */
1985 value = tvb_get_bits8(tvb, bo, bl);
1986 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
1988 proto_item_append_text(pi, "Access Technology Type: %s (%#01x)",
1989 translate_msrac_access_technology_type(value),
1993 value = tvb_get_bits8(tvb, bo, bl);
1994 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
1996 proto_item_append_text(pi, "GMSK Power Class: Power class %u", value);
1999 value = tvb_get_bits8(tvb, bo, bl);
2000 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2002 proto_item_append_text(pi, "8PSK Power Class");
2004 proto_item_append_text(pi, ": 8PSK modulation not supported for uplink");
2007 proto_item_append_text(pi, ": Power Class E%u", value);
2012 struct_bits_exist(guint64 start_bo, guint32 struct_length,
2013 guint64 bo, guint32 num_bits) {
2014 return (bo + num_bits) <= (start_bo + struct_length);
2019 decode_msrac_access_capabilities(proto_tree *tree, tvbuff_t *tvb,
2020 guint64 bo, guint32 struct_length) {
2022 - Struct too short: assume features do not exist
2023 - Struct too long: ignore data and jump to next Access Technology */
2024 proto_item *ti, *pi;
2027 guint8 dgmsc = 0, demsc = 0; /* DTM GPRS/EGPRS Multi Slot Class */
2028 guint8 bl; /* Bit length */
2029 guint64 start_bo = bo;
2031 /* RF Power Capability */
2033 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2034 value = tvb_get_bits8(tvb, bo, bl);
2035 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2037 proto_item_append_text(pi, "RF Power Capability");
2039 proto_item_append_text(pi, ": The MS does not support any GSM access technology type");
2042 proto_item_append_text(pi, ": GMSK Power Class %u", value);
2047 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2048 value = tvb_get_bits8(tvb, bo, bl);
2052 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2053 value = tvb_get_bits8(tvb, bo, bl);
2054 ti = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2055 proto_item_append_text(ti, "A5 Bits: %#02x", value);
2056 tf = proto_item_add_subtree(ti, ett_bssgp_msrac_a5_bits);
2057 for (i = 0; i < bl; i++) {
2058 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo + i, 1);
2059 proto_item_append_text(pi, "Encryption algorithm A5/%u%s available",
2061 value & (0x40 >> i) ? "" : " not");
2066 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2068 proto_item_append_text(pi, "A5 bits: Same as in the immediately preceding Access capabilities field within this IE");
2073 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2074 value = tvb_get_bits8(tvb, bo, bl);
2075 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2077 proto_item_append_text(pi, "ESD IND: Controlled Early Classmark Sending"" option is%s implemented",
2078 value == 0 ? " not" : "");
2082 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2083 value = tvb_get_bits8(tvb, bo, bl);
2084 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2086 proto_item_append_text(pi, "PS: PS capability%s present",
2087 value == 0 ? " not" : "");
2091 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2092 value = tvb_get_bits8(tvb, bo, bl);
2093 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2095 proto_item_append_text(pi, "VBCS:%s VGCS capability %s notifications wanted",
2096 value == 0 ? " No" : "",
2097 value == 0 ? "or no" : "and");
2101 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2102 value = tvb_get_bits8(tvb, bo, bl);
2103 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2105 proto_item_append_text(pi, "VBS:%s VBS capability %s notifications wanted",
2106 value == 0 ? " No" : "",
2107 value == 0 ? "or no" : "and");
2109 /* Multislot capability */
2110 /* XXX: 'Error: struct too short, assume features do not exist'
2111 No length is given! */
2113 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2114 value = tvb_get_bits8(tvb, bo, bl);
2118 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2119 ti = bit_proto_tree_add_text(tree, tvb, bo, bl, "Multislot capability");
2120 /* Temporary length */
2122 tf = proto_item_add_subtree(ti, ett_bssgp_msrac_multislot_capability);
2124 /* HSCSD Multislot Class */
2126 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2127 value = tvb_get_bits8(tvb, bo, bl);
2131 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2132 value = tvb_get_bits8(tvb, bo, bl);
2133 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2135 proto_item_append_text(pi, "HSCSD Multislot Class");
2136 if ((value > 0 ) && (value < 19)) {
2137 proto_item_append_text(pi, ": Multislot Class %u", value);
2140 proto_item_append_text(pi, ": Reserved");
2144 /* GPRS Multislot Class, GPRS Extended Dynamic Allocation Capability */
2146 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2147 value = tvb_get_bits8(tvb, bo, bl);
2151 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2152 value = tvb_get_bits8(tvb, bo, bl);
2153 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2155 proto_item_append_text(pi, "GPRS Multislot Class: Multislot Class %u",
2159 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2160 value = tvb_get_bits8(tvb, bo, bl);
2161 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2163 proto_item_append_text(pi, "GPRS Extended Dynamic Allocation Capability: Extended Dynamic Allocation for GPRS is%s implemented",
2164 value == 0 ? " not" : "");
2167 /* SMS Value, SM Value */
2169 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2170 value = tvb_get_bits8(tvb, bo, bl);
2174 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2175 value = tvb_get_bits8(tvb, bo, bl);
2176 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2178 proto_item_append_text(pi,
2179 "SMS_VALUE: %u/4 timeslot (~%u microseconds)",
2180 value + 1, (value + 1) * 144);
2183 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2184 value = tvb_get_bits8(tvb, bo, bl);
2185 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2187 proto_item_append_text(pi,
2188 "SM_VALUE: %u/4 timeslot (~%u microseconds)",
2189 value + 1, (value + 1) * 144);
2191 /* Additions in release 99 */
2193 /* ECSD Multislot Class */
2195 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2196 value = tvb_get_bits8(tvb, bo, bl);
2200 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2201 value = tvb_get_bits8(tvb, bo, bl);
2202 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2204 proto_item_append_text(pi, "ECSD Multislot Class");
2205 if ((value > 0 ) && (value < 19)) {
2206 proto_item_append_text(pi, ": Multislot Class %u", value);
2209 proto_item_append_text(pi, ": Reserved");
2213 /* EGPRS Multislot Class, EGPRS Extended Dynamic Allocation Capability */
2215 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2216 value = tvb_get_bits8(tvb, bo, bl);
2220 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2221 value = tvb_get_bits8(tvb, bo, bl);
2222 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2224 proto_item_append_text(pi, "EGPRS Multislot Class: Multislot Class %u",
2228 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2229 value = tvb_get_bits8(tvb, bo, bl);
2230 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2232 proto_item_append_text(pi, "EGPRS Extended Dynamic Allocation Capability: Extended Dynamic Allocation for EGPRS is%s implemented",
2233 value == 0 ? " not" : "");
2236 /* DTM GPRS Multislot Class */
2238 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2239 value = tvb_get_bits8(tvb, bo, bl);
2243 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2244 dgmsc = tvb_get_bits8(tvb, bo, bl);
2245 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2247 proto_item_append_text(pi, "DTM GPRS Multislot Class: %s",
2248 translate_msrac_dtm_gprs_multislot_class(dgmsc));
2250 /* Single slot DTM */
2252 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2253 value = tvb_get_bits8(tvb, bo, bl);
2254 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2256 proto_item_append_text(pi,
2257 "Single Slot DTM: Single slot DTM%s supported",
2258 value == 0 ? " not" : "");
2260 /* DTM EGPRS Multislot Class */
2262 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2263 value = tvb_get_bits8(tvb, bo, bl);
2267 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2268 demsc = tvb_get_bits8(tvb, bo, bl);
2269 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2271 proto_item_append_text(pi, "DTM EGPRS Multislot Class: %s",
2272 translate_msrac_dtm_gprs_multislot_class(demsc));
2275 proto_item_set_len(ti, get_num_octets_spanned(start_bo,
2276 (guint32) (bo - start_bo)));
2279 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2281 proto_item_append_text(pi, "Multislot capability: Same as in the immediately preceding Access capabilities field within this IE");
2284 /* Additions in release 99 */
2286 /* 8PSK Power Capability */
2288 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2289 value = tvb_get_bits8(tvb, bo, bl);
2293 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2294 value = tvb_get_bits8(tvb, bo, bl);
2295 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2297 proto_item_append_text(pi, "8PSK Power Capability");
2300 proto_item_append_text(pi, ": Reserved");
2303 proto_item_append_text(pi, ": Power Class E%u", value);
2305 proto_item_append_text(pi, ", 8PSK modulation capability in uplink");
2308 /* COMPACT Interference Measurement Capability */
2310 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2311 value = tvb_get_bits8(tvb, bo, bl);
2312 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2314 proto_item_append_text(pi,
2315 "COMPACT Interference Measurement Capability: %s",
2316 value == 0 ? "Not implemented" : "Implemented");
2318 /* Revision level indicator */
2320 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2321 value = tvb_get_bits8(tvb, bo, bl);
2322 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2324 proto_item_append_text(pi, "Revision Level Indicator: The ME is Release '%u %s",
2325 value == 0 ? 98 : 99,
2326 value == 0 ? "or older" : "onwards");
2331 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2332 value = tvb_get_bits8(tvb, bo, bl);
2333 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2335 proto_item_append_text(pi, "UMTS FDD Radio Access Technology Capability: UMTS FDD%s supported",
2336 value == 0 ? " not" : "");
2339 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2340 value = tvb_get_bits8(tvb, bo, bl);
2341 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2343 proto_item_append_text(pi, "UMTS 3.84 Mcps TDD Radio Access Technology Capability: UMTS 3.84 Mcps TDD%s supported",
2344 value == 0 ? " not" : "");
2347 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2348 value = tvb_get_bits8(tvb, bo, bl);
2349 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2351 proto_item_append_text(pi, "CDMA 2000 Radio Access Technology Capability: CDMA 2000%s supported",
2352 value == 0 ? " not" : "");
2355 /* Additions in release 4*/
2357 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2358 value = tvb_get_bits8(tvb, bo, bl);
2359 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2361 proto_item_append_text(pi, "UMTS 1.28 Mcps TDD Radio Access Technology Capability: UMTS 1.28 Mcps TDD%s supported",
2362 value == 0 ? " not" : "");
2365 /* GERAN Feature Package 1 */
2367 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2368 value = tvb_get_bits8(tvb, bo, bl);
2369 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2371 proto_item_append_text(pi, "GERAN Feature Package 1: GERAN Feature Package 1%s supported",
2372 value == 0 ? " not" : "");
2375 /* Extended DTM xGPRS Multislot Class */
2377 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2378 value = tvb_get_bits8(tvb, bo, bl);
2382 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2383 value = tvb_get_bits8(tvb, bo, bl);
2384 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2386 proto_item_append_text(pi, "Extended DTM GPRS Multi Slot Class: %s",
2387 translate_msrac_extended_dtm_gprs_multislot_class(value, dgmsc));
2389 /* XXX: 'This field shall be included only if the MS supports EGPRS DTM'.
2392 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2393 value = tvb_get_bits8(tvb, bo, bl);
2394 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2396 proto_item_append_text(pi, "Extended DTM EGPRS Multi Slot Class: %s",
2397 translate_msrac_extended_dtm_gprs_multislot_class(value, demsc));
2400 /* Modulation based multislot class support */
2402 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2403 value = tvb_get_bits8(tvb, bo, bl);
2404 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2406 proto_item_append_text(pi, "Modulation based multislot class support: %s supported",
2407 value == 0 ? "Not" : "");
2409 /* Additions in release 5 */
2411 /* High multislot capability */
2413 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2414 value = tvb_get_bits8(tvb, bo, bl);
2418 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2419 value = tvb_get_bits8(tvb, bo, bl);
2420 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2422 proto_item_append_text(pi, "High Multislot Capability: %u", value);
2423 /* XXX: Translate? In that case, which values to compare with?
2424 What if Multislot capability struct was not included? */
2427 /* GERAN Iu Mode Capabilities */
2428 /* XXX: Interpretation? Length? */
2430 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2431 value = tvb_get_bits8(tvb, bo, bl);
2432 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2434 proto_item_append_text(pi, "GERAN Iu Mode Capabilities: %s",
2435 value == 0 ? "Not supported" : "Supported");
2437 /* GMSK Multislot Power Profile */
2439 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2440 value = tvb_get_bits8(tvb, bo, bl);
2441 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2443 proto_item_append_text(pi, "GMSK Multislot Power Profile: GMSK_MULTI_SLOT_POWER_PROFILE %u",
2446 /* 8PSK Multislot Power Profile */
2447 /* XXX: 'If the MS does not support 8PSK in the uplink, then it shall
2448 set this field to 00' */
2450 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2451 value = tvb_get_bits8(tvb, bo, bl);
2452 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2454 proto_item_append_text(pi, "8PSK Multislot Power Profile: 8PSK_MULTI_SLOT_POWER_PROFILE %u",
2457 /* Additions in release 6 */
2459 /* Multiple TBF Capability */
2461 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2462 value = tvb_get_bits8(tvb, bo, bl);
2463 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2465 proto_item_append_text(pi, "Multiple TBF Capability: Multiple TBF procedures in A/Gb mode%s supported",
2466 value == 0 ? " not" : "");
2468 /* Downlink Advanced Receiver Performance */
2470 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2471 value = tvb_get_bits8(tvb, bo, bl);
2472 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2474 proto_item_append_text(pi, "Donwlink Advanced Receiver Performance: Downlink Advanced Receiver Performance %s supported",
2475 value == 0 ? "not" : "- phase 1");
2478 /* Extended RLC_MAC Control Message Segmentation Capability */
2480 if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return;
2481 value = tvb_get_bits8(tvb, bo, bl);
2482 pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl);
2484 proto_item_append_text(pi, "Extended RLC/MAC Control Message Segmentation Capability: Extended RLC/MAC Control Message Segmentation%s supported",
2485 value == 0 ? " not" : "");
2489 decode_msrac_value_part(proto_tree *tree, tvbuff_t *tvb, guint64 bo) {
2490 /* No need to check bi->bssgp_tree here */
2491 const guint8 ADD_ACC_TECHN = 0x0f;
2492 guint8 att, length, bit, bl;
2493 proto_item *ti, *ti2, *pi;
2494 proto_tree *tf, *tf2;
2495 const char *att_name;
2499 ti = bit_proto_tree_add_text(tree, tvb, bo, 8,
2500 "MS RA capability value part");
2501 /* Temporary length of item */
2502 tf = proto_item_add_subtree(ti, ett_bssgp_msrac_value_part);
2505 att = tvb_get_bits8(tvb, bo, bl);
2506 att_name = translate_msrac_access_technology_type(att);
2507 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2508 proto_item_append_text(pi, "Access Technology Type: %s (%#01x)", att_name, att);
2509 proto_item_append_text(ti, ": Technology Type %s", att_name);
2513 length = tvb_get_bits8(tvb, bo, bl);
2514 pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl);
2515 proto_item_append_text(pi, "Length: %u bits", length);
2518 if (att == ADD_ACC_TECHN) {
2519 bo++; /* Always '1' */
2520 ti2 = bit_proto_tree_add_text(tf, tvb, bo, length,
2521 "Additional Access Technologies");
2522 tf2 = proto_item_add_subtree(ti2, ett_bssgp_msrac_additional_access_technologies);
2523 proto_item_set_len(ti, get_num_octets_spanned(start_bo, 4 + 7 + length + 1 + 1));
2524 decode_msrac_additional_access_technologies(tf2, tvb, bo, length);
2526 else if (att <= 0x0b) {
2527 ti2 = bit_proto_tree_add_text(tf, tvb, bo, length, "Access Capabilities");
2528 tf2 = proto_item_add_subtree(ti2, ett_bssgp_msrac_access_capabilities);
2529 proto_item_set_len(ti, get_num_octets_spanned(start_bo, 4 + 7 + length + 1));
2530 decode_msrac_access_capabilities(tf2, tvb, bo, length);
2532 /* else unknown Access Technology Type */
2535 bit = tvb_get_bits8(tvb, bo, 1);
2538 decode_msrac_value_part(tree, tvb, bo);
2543 decode_iei_ms_radio_access_capability(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2547 if (!bi->bssgp_tree) {
2548 bi->offset += ie->value_length;
2551 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2552 tf = proto_item_add_subtree(ti, ett_bssgp_ms_radio_access_capability);
2554 decode_msrac_value_part(tf, bi->tvb, bi->offset * 8);
2555 bi->offset += ie->value_length;
2559 decode_iei_omc_id(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2560 /* XXX: Translation: where in 3GPP TS 12.20? */
2563 if (bi->bssgp_tree) {
2564 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2565 proto_item_append_text(ti, ": %s", BSSGP_NOT_DECODED);
2567 bi->offset += ie->value_length;
2571 decode_iei_pdu_in_error(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2574 if (bi->bssgp_tree) {
2575 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2576 proto_item_append_text(ti, ": Erroneous BSSGP PDU (%u bytes)",
2579 bi->offset += ie->value_length;
2583 decode_iei_priority(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2584 const guint8 MASK_PCI = 0x40;
2585 const guint8 MASK_PRIORITY_LEVEL = 0x3c;
2586 const guint8 MASK_QA = 0x02;
2587 const guint8 MASK_PVI = 0x01;
2588 proto_item *ti, *pi;
2592 static const value_string tab_priority_level[] = {
2594 { 1, "Priority Level 1 = highest priority" },
2595 { 2, "Priority Level 2 = 2nd highest priority" },
2596 { 3, "Priority Level 3 = 3rd highest priority" },
2597 { 4, "Priority Level 4 = 4th highest priority" },
2598 { 5, "Priority Level 5 = 5th highest priority" },
2599 { 6, "Priority Level 6 = 6th highest priority" },
2600 { 7, "Priority Level 7 = 7th highest priority" },
2601 { 8, "Priority Level 8 = 8th highest priority" },
2602 { 9, "Priority Level 9 = 9th highest priority" },
2603 { 10, "Priority Level 10 = 10th highest priority" },
2604 { 11, "Priority Level 11 = 11th highest priority" },
2605 { 12, "Priority Level 12 = 12th highest priority" },
2606 { 13, "Priority Level 13 = 13th highest priority" },
2607 { 14, "Priority Level 14 = lowest priority" },
2608 { 15, "Priority not used" },
2612 if (!bi->bssgp_tree) {
2613 bi->offset += ie->value_length;
2616 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2617 tf = proto_item_add_subtree(ti, ett_bssgp_priority);
2619 data = tvb_get_guint8(bi->tvb, bi->offset);
2621 value = get_masked_guint8(data, MASK_PCI);
2622 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
2624 proto_item_append_text(pi, "PCI: This allocation request %s preempt an existing connection",
2625 value == 0 ? "shall not" : "may");
2627 value = get_masked_guint8(data, MASK_PRIORITY_LEVEL);
2628 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_PRIORITY_LEVEL);
2629 proto_item_append_text(pi, "Priority Level: %s",
2630 val_to_str(value, tab_priority_level, ""));
2632 value = get_masked_guint8(data, MASK_QA);
2633 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_QA);
2634 proto_item_append_text(pi, "QA: Queuing%s allowed",
2635 value == 0 ? " not" : "");
2637 value = get_masked_guint8(data, MASK_PVI);
2638 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_PVI);
2639 proto_item_append_text(pi, "PVI: This connection %s be preempted by another allocation request",
2640 value == 0 ? "shall not" : "might");
2642 bi->offset += ie->value_length;
2646 decode_iei_qos_profile(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2647 const guint8 MASK_CR_BIT = 0x20;
2648 const guint8 MASK_T_BIT = 0x10;
2649 const guint8 MASK_A_BIT = 0x08;
2650 const guint8 MASK_PRECEDENCE = 0x07;
2651 proto_item *ti, *pi;
2654 guint16 peak_bit_rate;
2656 static const value_string tab_precedence_ul[] = {
2657 { 0, "High priority" },
2658 { 1, "Normal priority" },
2659 { 2, "Low priority" },
2663 static const value_string tab_precedence_dl[] = {
2664 { 0, "Radio priority 1" },
2665 { 1, "Radio priority 2" },
2666 { 2, "Radio priority 3" },
2667 { 3, "Radio priority 4" },
2668 { 4, "Radio priority unknown" },
2672 if (!bi->bssgp_tree) {
2673 bi->offset += ie->value_length;
2676 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2677 tf = proto_item_add_subtree(ti, ett_bssgp_qos_profile);
2679 peak_bit_rate = tvb_get_ntohs(bi->tvb, bi->offset);
2680 pi = proto_tree_add_text(tf, bi->tvb, bi->offset, 1, "Peak bit rate: ");
2681 if (peak_bit_rate == 0) {
2682 proto_item_append_text(pi, "Best effort");
2685 proto_item_append_text(pi, "%u bits/s", peak_bit_rate * 100);
2689 data = tvb_get_guint8(bi->tvb, bi->offset);
2691 value = get_masked_guint8(data, MASK_CR_BIT);
2692 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_CR_BIT);
2693 proto_item_append_text(pi, "C/R: The SDU %s command/response frame type",
2694 value == 0 ? "contains" : "does not contain");
2696 value = get_masked_guint8(data, MASK_T_BIT);
2697 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_T_BIT);
2698 proto_item_append_text(pi, "T: The SDU contains %s",
2701 "signalling (e.g. related to GMM)");
2703 value = get_masked_guint8(data, MASK_A_BIT);
2704 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_A_BIT);
2705 proto_item_append_text(pi, "A: Radio interface uses RLC/MAC %s functionality",
2706 value == 0 ? "ARQ " : "UNITDATA ");
2708 value = get_masked_guint8(data, MASK_PRECEDENCE);
2709 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_PRECEDENCE);
2710 proto_item_append_text(pi, "Precedence: ");
2713 proto_item_append_text(pi, val_to_str(value, tab_precedence_ul,
2714 "Reserved (Low priority)"));
2717 proto_item_append_text(pi, val_to_str(value, tab_precedence_dl,
2718 "Reserved (Radio priority 3)"));
2720 proto_item_append_text(pi, " (%#x)", value);
2725 decode_iei_radio_cause(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2729 static const value_string tab_radio_cause[] = {
2730 { 0x00, "Radio contact lost with the MS" },
2731 { 0x01, "Radio link quality insufficient to continue communication" },
2732 { 0x02, "Cell reselection ordered" },
2733 { 0x03, "Cell reselection prepare" },
2734 { 0x04, "Cell reselection failure" },
2736 /* Otherwise "Reserved (Radio contact lost with the MS)" */
2739 if (bi->bssgp_tree) {
2740 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2741 value = tvb_get_guint8(bi->tvb, bi->offset);
2742 proto_item_append_text(ti, ": %s (%#02x)",
2743 val_to_str(value, tab_radio_cause, "Reserved (Radio contact lost with the MS)"),
2746 bi->offset += ie->value_length;
2750 decode_iei_ra_cap_upd_cause(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2754 static const value_string tab_cause[] = {
2755 { 0x00, "OK, RA capability IE present" },
2756 { 0x01, "TLLI unknown in SGSN" },
2757 { 0x02, "No RA capabilities or IMSI available for this MS" },
2759 /* Otherwise "Reserved (TLLI unknown in SGSN)" */
2762 if (bi->bssgp_tree) {
2763 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2764 value = tvb_get_guint8(bi->tvb, bi->offset);
2765 proto_item_append_text(ti, ": %s (%#2x)",
2766 val_to_str(value, tab_cause, "Reserved (TLLI unknown in SGSN)"),
2769 bi->offset += ie->value_length;
2773 decode_iei_routeing_area(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2778 if (!bi->bssgp_tree) {
2779 bi->offset += ie->value_length;
2782 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2783 tf = proto_item_add_subtree(ti, ett_bssgp_routeing_area);
2785 rai = decode_rai(bi, tf);
2786 proto_item_append_text(ti, ": RAI %s", rai);
2790 decode_iei_tlli(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2795 tlli = tvb_get_ntohl(bi->tvb, bi->offset);
2797 if (bi->bssgp_tree) {
2798 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2799 proto_item_append_text(ti, ": %#04x", tlli);
2801 ti = bssgp_proto_tree_add_ie(ie, bi, bi->offset);
2802 tf = proto_item_add_subtree(ti, ett_bssgp_tlli);
2804 proto_tree_add_item(tf, hf_bssgp_tlli,
2805 bi->tvb, bi->offset, 4, BSSGP_LITTLE_ENDIAN);
2809 if (check_col(bi->pinfo->cinfo, COL_INFO)) {
2810 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP,
2813 decode_nri(bi->bssgp_tree, bi, tlli);
2817 decode_iei_trigger_id(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2818 /* XXX: value is 20 octets long! How add/show? */
2821 if (bi->bssgp_tree) {
2822 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2824 bi->offset += ie->value_length;
2828 proto_tree_add_lsa_id(build_info_t *bi, proto_tree *tree) {
2829 guint32 data, lsa_id;
2832 data = tvb_get_ntoh24(bi->tvb, bi->offset);
2835 pi = proto_tree_add_text(tree, bi->tvb, bi->offset, 3,
2836 "LSA ID: %#03x (%s)", lsa_id,
2838 "Universal LSA" : "PLMN significant number");
2843 decode_iei_lsa_identifier_list(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2844 const guint8 MASK_EP = 0x01;
2845 proto_item *ti, *pi;
2850 if (!bi->bssgp_tree) {
2851 bi->offset += ie->value_length;
2854 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2855 tf = proto_item_add_subtree(ti, ett_bssgp_lsa_identifier_list);
2857 value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_EP);
2858 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_EP);
2859 proto_item_append_text(pi, "EP: The escape PLMN is%s broadcast",
2860 value == 0 ? " not" : "");
2863 num_lsa_ids = (ie->value_length - 1) / 3;
2865 for (i = 0; i < num_lsa_ids; i++) {
2866 proto_tree_add_lsa_id(bi, tf);
2871 decode_iei_lsa_information(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2872 const guint8 MASK_LSA_ONLY = 0x01;
2873 const guint8 MASK_ACT = 0x20;
2874 const guint8 MASK_PREF = 0x10;
2875 const guint8 MASK_PRIORITY = 0x0f;
2876 proto_item *ti, *ti2, *pi;
2877 proto_tree *tf, *tf2;
2878 int num_lsa_infos, i;
2881 static const value_string tab_priority[] = {
2882 { 0, "Priority 1 = lowest priority" },
2883 { 1, "Priority 2 = 2nd lowest priority" },
2884 { 2, "Priority 3 = 3rd lowest priority" },
2885 { 3, "Priority 4 = 4th lowest priority" },
2886 { 4, "Priority 5 = 5th lowest priority" },
2887 { 5, "Priority 6 = 6th lowest priority" },
2888 { 6, "Priority 7 = 7th lowest priority" },
2889 { 7, "Priority 8 = 8th lowest priority" },
2890 { 8, "Priority 9 = 9th lowest priority" },
2891 { 9, "Priority 10 = 10th lowest priority" },
2892 { 10, "Priority 11 = 11th lowest priority" },
2893 { 11, "Priority 12 = 12th lowest priority" },
2894 { 12, "Priority 13 = 13th lowest priority" },
2895 { 13, "Priority 14 = 14th lowest priority" },
2896 { 14, "Priority 15 = 15th lowest priority" },
2897 { 15, "Priority 16 = highest priority" },
2901 if (!bi->bssgp_tree) {
2902 bi->offset += ie->value_length;
2905 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2906 tf = proto_item_add_subtree(ti, ett_bssgp_lsa_information);
2908 value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_LSA_ONLY);
2909 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_LSA_ONLY);
2910 proto_item_append_text(pi, "LSA Only: %s",
2912 "The subscriber has only access to the LSAs that are defined by the LSA information element" :
2913 "Allow an emergency call");
2916 num_lsa_infos = (ie->value_length - 1) / 4;
2918 for (i = 0; i < num_lsa_infos; i++) {
2919 ti2 = proto_tree_add_text(tf, bi->tvb, bi->offset, 4,
2920 "LSA Identification and attributes %u", i + 1);
2921 tf2 = proto_item_add_subtree(ti2, ett_bssgp_lsa_information_lsa_identification_and_attributes);
2923 data = tvb_get_guint8(bi->tvb, bi->offset);
2925 value = get_masked_guint8(data, MASK_ACT);
2926 pi = proto_tree_add_bitfield8(tf2, bi->tvb, bi->offset, MASK_ACT);
2927 proto_item_append_text(pi, "Act: The subscriber %s active mode support in the LSA",
2928 value == 0 ? "does not have" : "has");
2930 value = get_masked_guint8(data, MASK_PREF);
2931 pi = proto_tree_add_bitfield8(tf2, bi->tvb, bi->offset, MASK_PREF);
2932 proto_item_append_text(pi, "Pref: The subscriber %s preferential access in the LSA",
2933 value == 0 ? "does not have" : "has");
2935 value = get_masked_guint8(data, MASK_PRIORITY);
2936 pi = proto_tree_add_bitfield8(tf2, bi->tvb, bi->offset, MASK_PRIORITY);
2937 proto_item_append_text(pi, "Priority: %s",
2938 val_to_str(value, tab_priority, ""));
2941 proto_tree_add_lsa_id(bi, tf2);
2946 decode_iei_gprs_timer(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2947 const guint8 MASK_UNIT_VALUE = 0xe0;
2948 const guint8 MASK_TIMER_VALUE = 0x1f;
2952 static const value_string tab_unit_value[] = {
2953 { 0, "incremented in multiples of 2 s" },
2954 { 1, "incremented in multiples of 1 minute" },
2955 { 2, "incremented in multiples of decihours" },
2956 { 3, "incremented in multiples of 500 msec" },
2957 { 7, "the timer does not expire" },
2959 /* Otherwise "incremented in multiples of 1 minute" */
2962 if (bi->bssgp_tree) {
2963 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
2964 data = tvb_get_guint8(bi->tvb, bi->offset);
2965 value = get_masked_guint8(data, MASK_TIMER_VALUE);
2966 proto_item_append_text(ti, ": %u", value);
2968 value = get_masked_guint8(data, MASK_UNIT_VALUE);
2969 proto_item_append_text(ti, ", %s",
2970 val_to_str(value, tab_unit_value,
2971 "incremented in multiples of 1 minute"));
2973 bi->offset += ie->value_length;
2977 decode_iei_abqp(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
2978 const guint8 MASK_DELAY_CLASS = 0x38;
2979 const guint8 MASK_RELIABILITY_CLASS = 0x07;
2980 const guint8 MASK_PEAK_THROUGHPUT = 0xf0;
2981 const guint8 MASK_PRECEDENCE_CLASS = 0x07;
2982 const guint8 MASK_MEAN_THROUGHPUT = 0x1f;
2983 const guint8 MASK_TRAFFIC_CLASS = 0xe0;
2984 const guint8 MASK_DELIVERY_ORDER = 0x18;
2985 const guint8 MASK_DELIVERY_OF_ERRONEOUS_SDU = 0x07;
2986 const guint8 MASK_RESIDUAL_BER = 0xf0;
2987 const guint8 MASK_SDU_ERROR_RATIO = 0x0f;
2988 const guint8 MASK_TRANSFER_DELAY = 0xfc;
2989 const guint8 MASK_TRAFFIC_HANDLING_PRIORITY = 0x03;
2990 const guint8 MASK_SIGNALLING_INDICATION = 0x10;
2991 const guint8 MASK_SOURCE_STATISTICS_DESCRIPTOR = 0x0f;
2992 const guint8 TRAFFIC_CLASS_CONVERSATIONAL = 1;
2993 const guint8 TRAFFIC_CLASS_STREAMING = 2;
2994 const guint8 TRAFFIC_CLASS_INTERACTIVE = 3;
2995 const guint8 TRAFFIC_CLASS_BACKGROUND = 4;
2996 guint8 data, value, traffic_class;
2997 proto_item *ti, *pi;
3000 if (bi->bssgp_tree) {
3001 bi->offset += ie->value_length;
3004 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3005 tf = proto_item_add_subtree(ti, ett_bssgp_abqp);
3007 data = tvb_get_guint8(bi->tvb, bi->offset);
3009 value = get_masked_guint8(data, MASK_DELAY_CLASS);
3010 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_DELAY_CLASS);
3011 proto_item_append_text(pi, "Delay Class: %s (%#x)",
3012 translate_abqp_delay_class(value, bi), value);
3014 value = get_masked_guint8(data, MASK_RELIABILITY_CLASS);
3015 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3016 MASK_RELIABILITY_CLASS);
3017 proto_item_append_text(pi, "Reliability Class: %s (%#x)",
3018 translate_abqp_reliability_class(value, bi), value);
3020 data = tvb_get_guint8(bi->tvb, bi->offset);
3022 value = get_masked_guint8(data, MASK_PEAK_THROUGHPUT);
3023 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3024 MASK_PEAK_THROUGHPUT);
3025 proto_item_append_text(pi, "Peak Throughput: %s (%#x)",
3026 translate_abqp_peak_throughput(value, bi), value);
3028 value = get_masked_guint8(data, MASK_PRECEDENCE_CLASS);
3029 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3030 MASK_PRECEDENCE_CLASS);
3031 proto_item_append_text(pi, "Precedence Class: %s (%#x)",
3032 translate_abqp_precedence_class(value, bi), value);
3034 data = tvb_get_guint8(bi->tvb, bi->offset);
3036 value = get_masked_guint8(data, MASK_MEAN_THROUGHPUT);
3037 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3038 MASK_MEAN_THROUGHPUT);
3039 proto_item_append_text(pi, "Mean Throughput: %s (%#02x)",
3040 translate_abqp_mean_throughput(value, bi), value);
3042 data = tvb_get_guint8(bi->tvb, bi->offset);
3044 traffic_class = get_masked_guint8(data, MASK_TRAFFIC_CLASS);
3045 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_TRAFFIC_CLASS);
3046 proto_item_append_text(pi, "Traffic Class: %s (%#x)",
3047 translate_abqp_traffic_class(traffic_class, bi),
3049 if ((traffic_class == TRAFFIC_CLASS_INTERACTIVE) ||
3050 (traffic_class == TRAFFIC_CLASS_BACKGROUND)) {
3051 proto_item_append_text(pi, " (ignored)");
3054 value = get_masked_guint8(data, MASK_DELIVERY_ORDER);
3055 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_DELIVERY_ORDER);
3056 proto_item_append_text(pi, "Delivery Order: %s (%#x)",
3057 translate_abqp_delivery_order(value, bi), value);
3059 value = get_masked_guint8(data, MASK_DELIVERY_OF_ERRONEOUS_SDU);
3060 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3061 MASK_DELIVERY_OF_ERRONEOUS_SDU);
3062 proto_item_append_text(pi, "Delivery of Erroneous SDU: %s (%#x)",
3063 translate_abqp_delivery_of_erroneous_sdu(value, bi),
3067 value = tvb_get_guint8(bi->tvb, bi->offset);
3068 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
3069 "Maximum SDU Size: %s",
3070 translate_abqp_max_sdu_size(value, bi));
3073 value = tvb_get_guint8(bi->tvb, bi->offset);
3074 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
3075 "Maximum bit rate for uplink: %s",
3076 translate_abqp_max_bit_rate_for_ul(value, bi));
3079 value = tvb_get_guint8(bi->tvb, bi->offset);
3080 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
3081 "Maximum bit rate for downlink: %s",
3082 translate_abqp_max_bit_rate_for_dl(value, bi));
3084 data = tvb_get_guint8(bi->tvb, bi->offset);
3086 value = get_masked_guint8(data, MASK_RESIDUAL_BER);
3087 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_RESIDUAL_BER);
3088 proto_item_append_text(pi, "Residual BER: %s (%#x)",
3089 translate_abqp_residual_ber(value, bi), value);
3091 value = get_masked_guint8(data, MASK_SDU_ERROR_RATIO);
3092 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3093 MASK_SDU_ERROR_RATIO);
3094 proto_item_append_text(pi, "SDU Error Ratio: %s (%#x)",
3095 translate_abqp_sdu_error_ratio(value, bi), value);
3097 data = tvb_get_guint8(bi->tvb, bi->offset);
3099 value = get_masked_guint8(data, MASK_TRANSFER_DELAY);
3100 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_TRANSFER_DELAY);
3101 proto_item_append_text(pi, "Transfer Delay: %s (%#02x)",
3102 translate_abqp_transfer_delay(value, bi), value);
3104 value = get_masked_guint8(data, MASK_TRAFFIC_HANDLING_PRIORITY);
3105 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3106 MASK_TRAFFIC_HANDLING_PRIORITY);
3107 proto_item_append_text(pi, "Traffic Handling Priority: %s (%#x)",
3108 translate_abqp_traffic_handling_priority(value, bi),
3110 if ((traffic_class == TRAFFIC_CLASS_CONVERSATIONAL) ||
3111 (traffic_class == TRAFFIC_CLASS_STREAMING) ||
3112 (traffic_class == TRAFFIC_CLASS_BACKGROUND)) {
3113 proto_item_append_text(pi, " (ignored)");
3117 value = tvb_get_guint8(bi->tvb, bi->offset);
3118 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
3119 "Guaranteed bit rate for uplink: %s",
3120 translate_abqp_guaranteed_bit_rate_for_ul(value, bi));
3123 value = tvb_get_guint8(bi->tvb, bi->offset);
3124 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
3125 "Guaranteed bit rate for downlink: %s",
3126 translate_abqp_guaranteed_bit_rate_for_dl(value, bi));
3129 data = tvb_get_guint8(bi->tvb, bi->offset);
3131 value = get_masked_guint8(data, MASK_SIGNALLING_INDICATION);
3132 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3133 MASK_SIGNALLING_INDICATION);
3134 proto_item_append_text(pi, "Signalling Indication: %s for signalling traffic",
3135 value == 0 ? "Not optimized" : "Optimized");
3136 if ((traffic_class == TRAFFIC_CLASS_CONVERSATIONAL) ||
3137 (traffic_class == TRAFFIC_CLASS_STREAMING) ||
3138 (traffic_class == TRAFFIC_CLASS_BACKGROUND)) {
3139 proto_item_append_text(pi, " (ignored)");
3142 value = get_masked_guint8(data, MASK_SOURCE_STATISTICS_DESCRIPTOR);
3143 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3144 MASK_SOURCE_STATISTICS_DESCRIPTOR);
3145 proto_item_append_text(pi, "Source Statistics Descriptor: %s (%#x)",
3146 translate_abqp_source_statistics_descriptor(value, bi),
3148 if ((traffic_class == TRAFFIC_CLASS_INTERACTIVE) ||
3149 (traffic_class == TRAFFIC_CLASS_BACKGROUND)) {
3150 proto_item_append_text(pi, " (ignored)");
3154 value = tvb_get_guint8(bi->tvb, bi->offset);
3155 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
3156 "Maximum bit rate for downlink (extended): %s",
3157 translate_abqp_max_bit_rate_for_dl_extended(value, bi));
3160 value = tvb_get_guint8(bi->tvb, bi->offset);
3161 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
3162 "Guaranteed bit rate for downlink (extended): %s",
3163 translate_abqp_guaranteed_bit_rate_for_dl_extended(value, bi));
3168 decode_iei_feature_bitmap(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3169 const guint8 MASK_ENHANCED_RADIO_STATUS = 0x40;
3170 const guint8 MASK_PFC_FC = 0x20;
3171 const guint8 MASK_RIM = 0x10;
3172 const guint8 MASK_LCS = 0x08;
3173 const guint8 MASK_INR = 0x04;
3174 const guint8 MASK_CBL = 0x02;
3175 const guint8 MASK_PFC = 0x01;
3176 proto_item *ti, *pi;
3180 if (!bi->bssgp_tree) {
3181 bi->offset += ie->value_length;
3184 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3185 tf = proto_item_add_subtree(ti, ett_bssgp_feature_bitmap);
3187 data = tvb_get_guint8(bi->tvb, bi->offset);
3189 value = get_masked_guint8(data, MASK_ENHANCED_RADIO_STATUS);
3190 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3191 MASK_ENHANCED_RADIO_STATUS);
3192 proto_item_append_text(pi, "Enhanced Radio Status: Enhanced Radio Status Procedures%s supported",
3193 value == 0 ? " not" : "");
3195 value = get_masked_guint8(data, MASK_PFC_FC);
3196 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_PFC_FC);
3197 proto_item_append_text(pi, "PFC_FC: PFC Flow Control Procedures%s supported",
3198 value == 0 ? " not" : "");
3200 value = get_masked_guint8(data, MASK_RIM);
3201 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_RIM);
3202 proto_item_append_text(pi, "RIM: RAN Information Management (RIM) Procedures%s supported",
3203 value == 0 ? " not" : "");
3205 value = get_masked_guint8(data, MASK_LCS);
3206 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_LCS);
3207 proto_item_append_text(pi, "LCS: LCS Procedures%s supported",
3208 value == 0 ? " not" : "");
3210 value = get_masked_guint8(data, MASK_INR);
3211 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_INR);
3212 proto_item_append_text(pi, "INR: Inter-NSE re-routeing%s supoprted",
3213 value == 0 ? " not" : "");
3215 value = get_masked_guint8(data, MASK_CBL);
3216 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_CBL);
3217 proto_item_append_text(pi, "CBL: Current Bucket Level Procedures%s supported",
3218 value == 0 ? " not" : "");
3220 value = get_masked_guint8(data, MASK_PFC);
3221 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_PFC);
3222 proto_item_append_text(pi, "PFC: Packet Flow Context Procedures%s supported",
3223 value == 0 ? " not" : "");
3225 bi->offset += ie->value_length;
3229 decode_iei_bucket_full_ratio(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3232 if (bi->bssgp_tree) {
3233 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3234 bssgp_pi_append_bucket_full_ratio(ti, bi->tvb, bi->offset);
3236 bi->offset += ie->value_length;
3240 decode_iei_service_utran_cco(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3241 const guint8 MASK_SERVICE_UTRAN_CCO = 0x07;
3245 static const value_string tab_service_utran_cco[] = {
3246 { 0, "Network initiated cell change order procedure to UTRAN should be performed" },
3247 { 1, "Network initiated cell change order procedure to UTRAN should not be performed" },
3248 { 2, "Network initiated cell change order procedure to UTRAN shall not be performed" },
3250 /* Otherwise "No information available" */
3253 if (bi->bssgp_tree) {
3254 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3255 data = tvb_get_guint8(bi->tvb, bi->offset);
3256 value = get_masked_guint8(data, MASK_SERVICE_UTRAN_CCO);
3257 proto_item_append_text(ti, ": %s (%#02x)",
3258 val_to_str(value, tab_service_utran_cco,
3259 "No information available"),
3262 bi->offset += ie->value_length;
3266 decode_iei_nsei(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3270 nsei = tvb_get_ntohs(bi->tvb, bi->offset);
3272 if (bi->bssgp_tree) {
3273 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3274 proto_item_append_text(ti, ": %u", nsei);
3275 proto_tree_add_item_hidden(bi->bssgp_tree, hf_bssgp_nsei,
3276 bi->tvb, bi->offset, 2, BSSGP_LITTLE_ENDIAN);
3278 bi->offset += ie->value_length;
3280 if (check_col(bi->pinfo->cinfo, COL_INFO)) {
3281 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP,
3287 decode_iei_lcs_qos(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3288 const guint8 MASK_VERT = 0x01;
3289 const guint8 MASK_XA = 0x80;
3290 const guint8 MASK_ACCURACY = 0x7f;
3291 const guint8 MASK_RT = 0xc0;
3292 proto_item *ti, *pi;
3294 guint8 data, value, vert;
3296 static const value_string tab_rt[] = {
3297 { 0, "Response time is not specified" },
3299 { 2, "Delay tolerant" },
3304 if (!bi->bssgp_tree) {
3305 bi->offset += ie->value_length;
3308 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3309 tf = proto_item_add_subtree(ti, ett_bssgp_lcs_qos);
3311 data = tvb_get_guint8(bi->tvb, bi->offset);
3312 vert = get_masked_guint8(data, MASK_VERT);
3313 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_VERT);
3314 proto_item_append_text(pi, "VERT: Vertical coordinate is%s requested",
3315 vert == 0 ? " not" : "");
3318 data = tvb_get_guint8(bi->tvb, bi->offset);
3320 value = get_masked_guint8(data, MASK_XA);
3321 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_XA);
3322 proto_item_append_text(pi, "HA: Horizontal Accuracy is%s specified",
3323 value == 0 ? " not" : "");
3326 value = get_masked_guint8(data, MASK_ACCURACY);
3327 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_ACCURACY);
3328 proto_item_append_text(pi, "Horizontal Accuracy: %.1f m",
3329 10 * (pow(1.1, (double)value) - 1));
3333 data = tvb_get_guint8(bi->tvb, bi->offset);
3336 value = get_masked_guint8(data, MASK_XA);
3337 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_XA);
3338 proto_item_append_text(pi, "VA: Vertical Accuracy is%s specified",
3339 value == 0 ? " not" : "");
3341 value = get_masked_guint8(data, MASK_ACCURACY);
3342 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_ACCURACY);
3343 proto_item_append_text(pi, "Vertical Accuracy: %.1f m",
3344 45 * (pow(1.025, (double)value) - 1));
3348 data = tvb_get_guint8(bi->tvb, bi->offset);
3349 value = get_masked_guint8(data, MASK_RT);
3351 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_RT);
3352 proto_item_append_text(pi, "RT: %s",
3353 val_to_str(value, tab_rt, ""));
3358 decode_iei_lcs_client_type(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3359 const guint8 MASK_CATEGORY = 0xf0;
3360 const guint8 MASK_SUBTYPE = 0x0f;
3361 proto_item *ti, *pi;
3363 guint8 data, category, subtype;
3365 static const value_string tab_category[] = {
3366 { 0, "Value Added Client" },
3367 /* { 1, ??? XXX }, */
3368 { 2, "PLMN Operator" },
3369 { 3, "Emergency Services" },
3370 { 4, "Lawful Intercept Services" },
3372 /* Otherwise "Reserved" */
3375 if (!bi->bssgp_tree) {
3376 bi->offset += ie->value_length;
3379 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3380 tf = proto_item_add_subtree(ti, ett_bssgp_lcs_client_type);
3382 data = tvb_get_guint8(bi->tvb, bi->offset);
3384 category = get_masked_guint8(data, MASK_CATEGORY);
3385 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_CATEGORY);
3386 proto_item_append_text(pi, "Category: %s (%#x)",
3387 val_to_str(category, tab_category, "Reserved"),
3390 subtype = get_masked_guint8(data, MASK_SUBTYPE);
3391 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_SUBTYPE);
3392 proto_item_append_text(pi, "Subtype: ");
3397 proto_item_append_text(pi, "Unspecified"); break;
3400 proto_item_append_text(pi, "Reserved"); break;
3402 /* case 1: ??? XXX*/
3405 case 0: proto_item_append_text(pi, "Unspecified"); break;
3406 case 1: proto_item_append_text(pi, "Broadcast service"); break;
3407 case 2: proto_item_append_text(pi, "O&M"); break;
3408 case 3: proto_item_append_text(pi, "Anonymous statistics"); break;
3409 case 4: proto_item_append_text(pi, "Target MS service support node"); break;
3410 default: proto_item_append_text(pi, "Reserved"); break;
3416 proto_item_append_text(pi, "Unspecified"); break;
3419 proto_item_append_text(pi, "Reserved"); break;
3421 default: /* Not category == 1! */
3422 proto_item_append_text(pi, "Reserved"); break;
3429 decode_iei_requested_gps_assistance_data(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3430 const guint8 MASK_A = 0x01;
3431 const guint8 MASK_B = 0x02;
3432 const guint8 MASK_C = 0x04;
3433 const guint8 MASK_D = 0x08;
3434 const guint8 MASK_E = 0x10;
3435 const guint8 MASK_F = 0x20;
3436 const guint8 MASK_G = 0x40;
3437 const guint8 MASK_H = 0x80;
3438 const guint8 MASK_I = 0x01;
3439 const guint8 MASK_NSAT = 0xf0;
3440 const guint8 MASK_T_TOE_LIMIT = 0x0f;
3441 const guint8 MASK_SAT_ID =0x3f;
3442 proto_tree *tf, *tf2;
3443 proto_item *ti, *ti2, *pi;
3444 guint8 data, value, d, nsat;
3448 if (!bi->bssgp_tree) {
3449 bi->offset += ie->value_length;
3452 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3453 tf = proto_item_add_subtree(ti, ett_bssgp_requested_gps_assistance_data);
3455 data = tvb_get_guint8(bi->tvb, bi->offset);
3457 value = get_masked_guint8(data, MASK_A);
3458 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_A);
3459 proto_item_append_text(pi, "A: Almanac is%s srequested",
3460 value == 0 ? " not" : "");
3462 value = get_masked_guint8(data, MASK_B);
3463 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_B);
3464 proto_item_append_text(pi, "B: UTC Model is%s requested",
3465 value == 0 ? " not" : "");
3467 value = get_masked_guint8(data, MASK_C);
3468 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_C);
3469 proto_item_append_text(pi, "C: Ionospheric Model is%s requested",
3470 value == 0 ? " not" : "");
3472 value = get_masked_guint8(data, MASK_D);
3473 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_D);
3474 proto_item_append_text(pi, "D: Navigation Model is%s requested",
3475 value == 0 ? " not" : "");
3478 value = get_masked_guint8(data, MASK_E);
3479 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_E);
3480 proto_item_append_text(pi, "E: DGPS Corrections are%s requested",
3481 value == 0 ? " not" : "");
3483 value = get_masked_guint8(data, MASK_F);
3484 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_F);
3485 proto_item_append_text(pi, "F: Reference Location is%s requested",
3486 value == 0 ? " not" : "");
3488 value = get_masked_guint8(data, MASK_G);
3489 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_G);
3490 proto_item_append_text(pi, "G: Reference Time is%s requested",
3491 value == 0 ? " not" : "");
3493 value = get_masked_guint8(data, MASK_H);
3494 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_H);
3495 proto_item_append_text(pi, "H: Acquisition Asssistance is%s requested",
3496 value == 0 ? " not" : "");
3500 value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_I);
3501 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_I);
3502 proto_item_append_text(pi, "I: Real-Time Integrity is%s requested",
3503 value == 0 ? " not" : "");
3506 data = tvb_get_guint8(bi->tvb, bi->offset);
3507 gps_week = (data & 0xc0) << 2;
3508 data = tvb_get_guint8(bi->tvb, bi->offset + 1);
3510 proto_tree_add_text(tf, bi->tvb, bi->offset, 2,
3511 "GPS Week: %u", gps_week);
3514 value = tvb_get_guint8(bi->tvb, bi->offset);
3515 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
3516 "GPS Toe: %u", value);
3519 data = tvb_get_guint8(bi->tvb, bi->offset);
3520 nsat = get_masked_guint8(data, MASK_NSAT);
3521 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_NSAT);
3522 proto_item_append_text(pi, "NSAT: %u", value);
3524 value = get_masked_guint8(data, MASK_T_TOE_LIMIT);
3525 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_T_TOE_LIMIT);
3526 proto_item_append_text(pi, "T-Toe Limit: %u", value);
3529 for (i = 0; i < nsat; i++) {
3530 ti2 = proto_tree_add_text(tf, bi->tvb, bi->offset, 2, "Satellite %u", i);
3531 tf2 = proto_item_add_subtree(ti2, ett_bssgp_requested_gps_assistance_data_satellite);
3533 value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_SAT_ID);
3534 pi = proto_tree_add_bitfield8(tf2, bi->tvb, bi->offset, MASK_SAT_ID);
3535 proto_item_append_text(pi, "SatId: %u", value);
3536 proto_item_append_text(ti2, ": Id %u", value);
3539 value = tvb_get_guint8(bi->tvb, bi->offset);
3540 proto_tree_add_text(tf2, bi->tvb, bi->offset, 1,
3542 proto_item_append_text(ti2, ", IODE %u", value);
3548 decode_iei_location_type(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3549 const guint8 LOCATION_ASSISTANCE = 1;
3550 const guint8 DECIPHERING_KEYS = 2;
3555 static const value_string tab_location_information[] = {
3556 { 0, "Current geographic location" },
3557 { 1, "Location assistance information for the target MS" },
3558 { 2, "Deciphering keys for broadcast assistance data for the target MS" },
3560 /* Otherwise "Reserved" */
3563 static const value_string tab_positioning_method[] = {
3565 { 1, "Mobile Assisted E-OTD" },
3566 { 2, "Mobile Based E-OTD" },
3567 { 3, "Assisted GPS" },
3569 /* Otherwise "Reserved" */
3572 if (!bi->bssgp_tree) {
3573 bi->offset += ie->value_length;
3576 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3577 tf = proto_item_add_subtree(ti, ett_bssgp_location_type);
3579 value = tvb_get_guint8(bi->tvb, bi->offset);
3580 proto_tree_add_text(tf, bi->tvb, bi->offset, 1, "Location Information: %s",
3581 val_to_str(value, tab_location_information,
3585 if ((value == LOCATION_ASSISTANCE) || (value == DECIPHERING_KEYS)) {
3586 value = tvb_get_guint8(bi->tvb, bi->offset);
3587 proto_tree_add_text(tf, bi->tvb, bi->offset, 1, "Positioning Method: %s",
3588 val_to_str(value, tab_positioning_method,
3595 decode_iei_location_estimate(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3596 /* XXX: Which paragraph in 3GPP TS 23.032?*/
3599 if (bi->bssgp_tree) {
3600 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3601 proto_item_append_text(ti, ": %s", BSSGP_NOT_DECODED);
3603 if (ie->value_length != BSSGP_UNKNOWN) {
3604 bi->offset += ie->value_length;
3609 decode_iei_positioning_data(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3610 const guint8 MASK_PDD = 0x0f;
3611 const guint8 MASK_METHOD = 0xf8;
3612 const guint8 MASK_USAGE = 0x07;
3613 proto_item *ti, *pi;
3615 guint8 data, value, i, num_methods;
3617 if (!bi->bssgp_tree) {
3618 bi->offset += ie->value_length;
3621 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3622 tf = proto_item_add_subtree(ti, ett_bssgp_positioning_data);
3624 value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_PDD);
3625 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_PDD);
3626 proto_item_append_text(pi, "Positioning Data Discriminator: %s",
3628 "Indicate usage of each positioning method that was attempted either successfully or unseccessfully" :
3632 num_methods = ie->value_length - 1;
3633 for (i = 0; i < num_methods; i++) {
3634 data = tvb_get_guint8(bi->tvb, bi->offset);
3636 value = get_masked_guint8(data, MASK_METHOD);
3637 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_METHOD);
3638 proto_item_append_text(pi, "Method: ");
3641 case 0: proto_item_set_text(pi, "Timing Advance"); break;
3642 case 1: proto_item_set_text(pi, "Reserved"); break;
3643 case 2: proto_item_set_text(pi, "Reserved"); break;
3644 case 3: proto_item_set_text(pi, "Mobile Assisted E-OTD"); break;
3645 case 4: proto_item_set_text(pi, "Mobile Based E-OTD"); break;
3646 case 5: proto_item_set_text(pi, "Mobile Assisted GPS"); break;
3647 case 6: proto_item_set_text(pi, "Mobile Based GPS"); break;
3648 case 7: proto_item_set_text(pi, "Conventional GPS"); break;
3649 case 8: proto_item_set_text(pi, "U-TDOA"); break;
3651 if ((value >= 9) && (value <= 0x0f)) {
3652 proto_item_set_text(pi, "Reserved for GSM");
3655 proto_item_set_text(pi, "Reserved for network specific positioning methods");
3658 proto_item_append_text(pi, " (%#02x)", value); /* Method */
3660 value = get_masked_guint8(data, MASK_USAGE);
3663 case 0: proto_item_append_text(pi, " attempted unsuccessfully due to failure or interuption "); break;
3664 case 1: proto_item_append_text(pi, " attempted successfully: results not used to generate location"); break;
3665 case 2: proto_item_append_text(pi, " attempted successfully: results used to verify but not generate location"); break;
3666 case 3: proto_item_append_text(pi, "attempted successfully: results used to generate location"); break;
3667 case 4: proto_item_append_text(pi, "a temmpted successfully: case where MS supports multiple mobile based positioning methods and the actual method or methods used by the MS cannot be determined"); break;
3668 default: ; /* ??? */
3670 proto_item_append_text(pi, " (%#x)", value); /* Usage */
3676 decode_iei_deciphering_keys(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3677 const guint8 MASK_KEY_FLAG = 0x01;
3678 proto_item *ti, *pi;
3682 if (!bi->bssgp_tree) {
3683 bi->offset += ie->value_length;
3687 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3688 tf = proto_item_add_subtree(ti, ett_bssgp_deciphering_keys);
3690 data = tvb_get_guint8(bi->tvb, bi->offset);
3691 value = get_masked_guint8(data, MASK_KEY_FLAG);
3692 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_KEY_FLAG);
3693 proto_item_append_text(pi, "Ciphering Key Flag: %u", value);
3696 proto_tree_add_text(tf, bi->tvb, bi->offset, 7,
3697 "Current Deciphering Key Value");
3700 proto_tree_add_text(tf, bi->tvb, bi->offset, 7,
3701 "Next Deciphering Key Value");
3706 decode_iei_lcs_priority(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3707 /* XXX: coding (3GPP TS 29.002 7.6.11.7)? */
3710 if (bi->bssgp_tree) {
3711 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3712 proto_item_append_text(ti, ": %s", BSSGP_NOT_DECODED);
3714 bi->offset += ie->value_length;
3718 decode_iei_lcs_cause(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3723 static const value_string tab_cause_value[] = {
3724 { 0, "Unspecified" },
3725 { 1, "System failure" },
3726 { 2, "Protocol error" },
3727 { 3, "Data missing in position request" },
3728 { 4, "Unexpected value in position request" },
3729 { 5, "Position method failure" },
3730 { 6, "Target MS unreacheable" },
3731 { 7, "Location request aborted" },
3732 { 8, "Facility not supported" },
3733 { 9, "Inter-BSC handover ongoing" },
3734 { 10, "Intra-BSC handover ongoing" },
3735 { 11, "Congestion" },
3736 { 12, "Inter NSE cell change" },
3737 { 13, "Routeing area update" },
3738 { 14, "PTMSI reallocation" },
3739 { 15, "Suspension of GPRS services" },
3741 /* Otherwise "Unspecified" */
3744 static const value_string tab_diagnostic_value[] = {
3745 { 0, "Congestion" },
3746 { 1, "Insufficient resources" },
3747 { 2, "Insufficient measurement data" },
3748 { 3, "Inconsistent measurement data" },
3749 { 4, "Location procedure not completed" },
3750 { 5, "Location procedure not supported by target MS" },
3751 { 6, "QoS not attainable" },
3752 { 7, "Position method not available in network" },
3753 { 8, "Position method not available in location area" },
3755 /* Otherwise "Unrecognized => ignored" */
3758 if (!bi->bssgp_tree) {
3759 bi->offset += ie->value_length;
3762 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3763 value = tvb_get_guint8(bi->tvb, bi->offset);
3765 if (ie->value_length == 1) {
3766 /* Diagnostic value not included */
3767 proto_item_append_text(ti, ": %s (%#02x)",
3768 val_to_str(value, tab_cause_value, "Unspecified"),
3774 tf = proto_item_add_subtree(ti, ett_bssgp_lcs_cause);
3776 proto_tree_add_text(tf, bi->tvb, bi->offset, 1, ": %s (%#02x)",
3777 val_to_str(value, tab_cause_value, "Unspecified"),
3781 value = tvb_get_guint8(bi->tvb, bi->offset);
3782 proto_tree_add_text(tf, bi->tvb, bi->offset, 1, ": %s (%#02x)",
3783 val_to_str(value, tab_diagnostic_value,
3784 "Unrecognized => ignored"),
3790 decode_iei_lcs_capability(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3791 const guint8 MASK_OTD_A = 0x10;
3792 const guint8 MASK_OTD_B = 0x08;
3793 const guint8 MASK_GPS_A = 0x04;
3794 const guint8 MASK_GPS_B = 0x02;
3795 const guint8 MASK_GPS_C = 0x01;
3796 proto_item *ti, *pi;
3800 if (!bi->bssgp_tree) {
3801 bi->offset += ie->value_length;
3804 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3805 tf = proto_item_add_subtree(ti, ett_bssgp_lcs_capability);
3807 data = tvb_get_guint8(bi->tvb, bi->offset);
3809 value = get_masked_guint8(data, MASK_OTD_A);
3810 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_OTD_A);
3811 proto_item_append_text(pi, "OTD-A: MS Assisted E-OTD%s supported",
3812 value == 0 ? " not" : "");
3814 value = get_masked_guint8(data, MASK_OTD_B);
3815 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_OTD_B);
3816 proto_item_append_text(pi, "OTD-B: MS Based E-OTD%s supported",
3817 value == 0 ? " not" : "");
3819 value = get_masked_guint8(data, MASK_GPS_A);
3820 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_GPS_A);
3821 proto_item_append_text(pi, "GPS-A: MS Assisted GPS%s supported",
3822 value == 0 ? " not" : "");
3824 value = get_masked_guint8(data, MASK_GPS_B);
3825 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_GPS_B);
3826 proto_item_append_text(pi, "GPS-B: MS Based GPS%s supported",
3827 value == 0 ? " not" : "");
3829 value = get_masked_guint8(data, MASK_GPS_C);
3830 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_GPS_C);
3831 proto_item_append_text(pi, "GPS-C: Conventional GPS%s supported",
3832 value == 0 ? " not" : "");
3838 decode_iei_rrlp_flags(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3839 const guint8 MASK_FLAG1 = 0x01;
3843 if (bi->bssgp_tree) {
3844 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3845 value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_FLAG1);
3846 proto_item_append_text(ti, ": Flag1:%s Position Command (BSS to SGSN) or final response (SGSN to BSS) (%u)",
3847 value == 0 ? " Not a" : "", value);
3853 decode_iei_rim_application_identity(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3857 if (bi->bssgp_tree) {
3858 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3859 value = tvb_get_guint8(bi->tvb, bi->offset);
3861 case 0: proto_item_append_text(ti, ": Reserved"); break;
3862 case 1: proto_item_append_text(ti, ": Network Assisted Cell Change (NACC)"); break;
3863 default: proto_item_append_text(ti, ": Reserved");
3870 decode_ran_information_common(build_info_t *bi, proto_tree *parent_tree) {
3874 guint8 num_rai_cis, i;
3876 ti = proto_tree_add_text(parent_tree, bi->tvb, bi->offset, 8,
3877 "RAI + CI for Source Cell");
3878 tf = proto_item_add_subtree(ti, ett_bssgp_rai_ci);
3880 rai_ci = decode_rai_ci(bi, tf);
3881 proto_item_append_text(ti, ": %s", rai_ci);
3883 num_rai_cis = tvb_get_guint8(bi->tvb, bi->offset);
3884 proto_tree_add_text(tf, bi->tvb, bi->offset, 1,
3885 "%u ""RAI+CI for Destination Cell"" follow%s",
3886 num_rai_cis, (num_rai_cis == 0) ? "" : "s");
3889 for (i = 0; i < num_rai_cis; i++) {
3890 ti = proto_tree_add_text(parent_tree, bi->tvb, bi->offset, 8,
3891 """RAI + CI for Destination Cell"" (%u)", i + 1);
3892 tf = proto_item_add_subtree(ti, ett_bssgp_rai_ci);
3893 rai_ci = decode_rai_ci(bi, tf);
3894 proto_item_append_text(ti, ": %s", rai_ci);
3899 decode_iei_ran_information_request_container_unit(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3903 if (! bi->bssgp_tree) {
3907 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3908 tf = proto_item_add_subtree(ti, ett_bssgp_ran_information_request_container_unit);
3910 decode_ran_information_common(bi, tf);
3914 decode_iei_ran_information_container_unit(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3915 const guint8 MASK_NUMBER_OF_SI_PSI = 0xfe;
3916 const guint8 MASK_UNIT_TYPE = 0x01;
3917 const guint8 TYPE_SI = 0;
3918 const guint8 TYPE_PSI = 1;
3919 const guint8 LEN_SI = 23;
3920 const guint8 LEN_PSI = 22;
3921 proto_item *ti, *pi;
3923 guint8 num_si_psi, type_si_psi, data, i;
3925 if (! bi->bssgp_tree) {
3929 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3930 tf = proto_item_add_subtree(ti, ett_bssgp_ran_information_container_unit);
3932 decode_ran_information_common(bi, tf);
3934 data = tvb_get_guint8(bi->tvb, bi->offset);
3935 num_si_psi = get_masked_guint8(data, MASK_NUMBER_OF_SI_PSI);
3936 type_si_psi = get_masked_guint8(data, MASK_UNIT_TYPE);
3938 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset,
3939 MASK_NUMBER_OF_SI_PSI);
3940 proto_item_append_text(pi, "Number of SI/PSI: %u ""SI/PSI"" follow%s",
3942 num_si_psi < 2 ? "s" : "");
3944 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_UNIT_TYPE);
3945 proto_item_append_text(pi, "Type: %s messages as specified for %s follow",
3946 type_si_psi == TYPE_SI ? "SI" : "PSI",
3947 type_si_psi == TYPE_SI ? "BCCH" : "PBCCH");
3951 for (i = 0; i < num_si_psi; i++) {
3952 if (type_si_psi == TYPE_SI) {
3953 proto_tree_add_text(tf, bi->tvb, bi->offset, LEN_SI,
3954 " SI (%u), %u octets", i + 1, LEN_SI);
3955 /* XXX: Not decoded yet; which section in 3GPP TS 44.018? */
3956 bi->offset += LEN_SI;
3958 else if (type_si_psi == TYPE_PSI) {
3959 proto_tree_add_text(tf, bi->tvb, bi->offset, LEN_PSI,
3960 " PSI (%u), %u octets", i + 1, LEN_PSI);
3961 /* XXX: Not decoded yet; which section in 3GPP TS 44.060? */
3962 bi->offset += LEN_PSI;
3968 decode_iei_ran_information_indications(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
3969 const guint8 MASK_END = 0x02;
3970 const guint8 MASK_ACK = 0x01;
3971 proto_item *ti, *pi;
3975 if (!bi->bssgp_tree) {
3976 bi->offset += ie->value_length;
3979 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
3980 tf = proto_item_add_subtree(ti, ett_bssgp_ran_information_indications);
3982 data = tvb_get_guint8(bi->tvb, bi->offset);
3984 value = get_masked_guint8(data, MASK_END);
3985 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_END);
3986 proto_item_append_text(pi, "END: %sEND indicated",
3987 value == 0 ? "No " : "");
3989 value = get_masked_guint8(data, MASK_ACK);
3990 pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_ACK);
3991 proto_item_append_text(pi, "ACK: %sACK requested",
3992 value == 0 ? "No " : "");
3997 decode_iei_number_of_container_units(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
4001 if (!bi->bssgp_tree) {
4002 bi->offset += ie->value_length;
4005 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
4006 value = tvb_get_guint8(bi->tvb, bi->offset);
4007 proto_item_append_text(ti, ": %u Container Unit%s follow%s",
4009 value == 0 ? "" : "s",
4010 value > 0 ? "s" : "");
4015 decode_iei_pfc_flow_control_parameters(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
4016 proto_tree *tf, *tf2;
4017 proto_item *ti, *ti2, *pi;
4018 guint8 num_pfc, i, pfc_len;
4019 gboolean b_pfc_included;
4021 if (!bi->bssgp_tree) {
4022 bi->offset += ie->value_length;
4025 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
4026 tf = proto_item_add_subtree(ti, ett_bssgp_pfc_flow_control_parameters);
4028 num_pfc = tvb_get_guint8(bi->tvb, bi->offset);
4029 pi = proto_tree_add_text(bi->bssgp_tree, bi->tvb, bi->offset, 1,
4030 "Number of PFCs: ");
4033 proto_item_append_text(pi, "%u", num_pfc);
4036 proto_item_append_text(pi, "Reserved");
4040 if (num_pfc == 0) return;
4042 pfc_len = (ie->value_length - 1) / num_pfc;
4043 b_pfc_included = (pfc_len == 6);
4045 for (i = 0; i < num_pfc; i++) {
4046 ti2 = proto_tree_add_text(tf, bi->tvb, bi->offset, pfc_len,
4048 tf2 = proto_item_add_subtree(ti2, ett_bssgp_pfc_flow_control_parameters_pfc);
4050 pi = proto_tree_add_text(tf2, bi->tvb, bi->offset, 1, "PFI");
4051 bssgp_pi_append_pfi(pi, bi->tvb, bi->offset);
4054 pi = proto_tree_add_text(tf2, bi->tvb, bi->offset, 2, "BMax_PFC");
4055 bssgp_pi_append_bucket_size(pi, bi->tvb, bi->offset);
4058 pi = proto_tree_add_text(tf2, bi->tvb, bi->offset, 2, "R_PFC");
4059 bssgp_pi_append_bucket_leak_rate(pi, bi->tvb, bi->offset);
4062 if (b_pfc_included) {
4063 pi = proto_tree_add_text(tf2, bi->tvb, bi->offset, 1, "B_PFC");
4064 bssgp_pi_append_bucket_full_ratio(pi, bi->tvb, bi->offset);
4071 decode_iei_global_cn_id(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
4077 if (!bi->bssgp_tree) {
4078 bi->offset += ie->value_length;
4081 ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset);
4082 tf = proto_item_add_subtree(ti, ett_bssgp_global_cn_id);
4084 mcc_mnc = decode_mcc_mnc(bi, tf);
4085 proto_item_append_text(ti, ": PLMN-Id %s", mcc_mnc);
4087 value = tvb_get_ntohs(bi->tvb, bi->offset);
4088 proto_tree_add_text(tf, bi->tvb, bi->offset, 2,
4089 "CN-ID: %u", value);
4090 proto_item_append_text(ti, ", CN-Id %u", value);
4095 decode_ie(bssgp_ie_t *ie, build_info_t *bi) {
4096 int org_offset = bi->offset;
4097 const char *iename = val_to_str(ie->iei, tab_bssgp_ie_types, "Unknown");
4098 gboolean use_default_ie_name = (ie->name == NULL);
4100 if (tvb_length_remaining(bi->tvb, bi->offset) < 1) {
4103 switch (ie->format) {
4104 case BSSGP_IE_FORMAT_TLV:
4105 if (!check_correct_iei(ie, bi)) {
4108 bi->offset++; /* Account for type */
4109 ie->total_length = 1;
4110 get_value_length(ie, bi);
4112 case BSSGP_IE_FORMAT_TV:
4113 if (!check_correct_iei(ie, bi)) {
4116 bi->offset++; /* Account for type */
4117 ie->value_length = ie->total_length - 1;
4119 case BSSGP_IE_FORMAT_V:
4120 ie->value_length = ie->total_length;
4126 if (use_default_ie_name) {
4127 ie->name = malloc(strlen(iename) + 1);
4128 if (ie->name == NULL) {
4130 proto_tree_add_text(bi->bssgp_tree, bi->tvb, bi->offset, 1,
4136 strcpy(ie->name, iename);
4140 case BSSGP_IEI_ALIGNMENT_OCTETS:
4141 decode_iei_alignment_octets(ie, bi, org_offset);
4143 case BSSGP_IEI_BMAX_DEFAULT_MS:
4144 decode_bucket_size(ie, bi, org_offset);
4146 case BSSGP_IEI_BSS_AREA_INDICATION:
4147 /* XXX: 'The recipient shall ignore the value of this octet'??? */
4148 decode_simple_ie(ie, bi, org_offset, "BSS Indicator", "", TRUE);
4150 case BSSGP_IEI_BUCKET_LEAK_RATE:
4151 decode_bucket_leak_rate(ie, bi, org_offset);
4153 case BSSGP_IEI_BVCI:
4154 decode_iei_bvci(ie, bi, org_offset);
4156 case BSSGP_IEI_BVC_BUCKET_SIZE:
4157 decode_bucket_size(ie, bi, org_offset);
4159 case BSSGP_IEI_BVC_MEASUREMENT:
4160 decode_queuing_delay(ie, bi, org_offset);
4162 case BSSGP_IEI_CAUSE:
4163 decode_iei_cause(ie, bi, org_offset);
4165 case BSSGP_IEI_CELL_IDENTIFIER:
4166 decode_iei_cell_identifier(ie, bi, org_offset);
4168 case BSSGP_IEI_CHANNEL_NEEDED:
4169 decode_iei_channel_needed(ie, bi, org_offset);
4171 case BSSGP_IEI_DRX_PARAMETERS:
4172 decode_iei_drx_parameters(ie, bi, org_offset);
4174 case BSSGP_IEI_EMLPP_PRIORITY:
4175 decode_iei_emlpp_priority(ie, bi, org_offset);
4177 case BSSGP_IEI_FLUSH_ACTION:
4178 decode_iei_flush_action(ie, bi, org_offset);
4180 case BSSGP_IEI_IMSI:
4181 decode_mobile_identity(ie, bi, org_offset);
4183 case BSSGP_IEI_LLC_PDU:
4184 bssgp_proto_handoff(ie, bi, org_offset, llc_handle);
4186 case BSSGP_IEI_LLC_FRAMES_DISCARDED:
4187 decode_iei_llc_frames_discarded(ie, bi, org_offset);
4189 case BSSGP_IEI_LOCATION_AREA:
4190 decode_iei_location_area(ie, bi, org_offset);
4192 case BSSGP_IEI_MOBILE_ID:
4193 decode_mobile_identity(ie, bi, org_offset);
4195 case BSSGP_IEI_MS_BUCKET_SIZE:
4196 decode_bucket_size(ie, bi, org_offset);
4198 case BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY:
4199 decode_iei_ms_radio_access_capability(ie, bi, org_offset);
4201 case BSSGP_IEI_OMC_ID:
4202 decode_iei_omc_id(ie, bi, org_offset);
4204 case BSSGP_IEI_PDU_IN_ERROR:
4205 decode_iei_pdu_in_error(ie, bi, org_offset);
4207 case BSSGP_IEI_PDU_LIFETIME:
4208 decode_queuing_delay(ie, bi, org_offset);
4210 case BSSGP_IEI_PRIORITY:
4211 decode_iei_priority(ie, bi, org_offset);
4213 case BSSGP_IEI_QOS_PROFILE:
4214 decode_iei_qos_profile(ie, bi, org_offset);
4216 case BSSGP_IEI_RADIO_CAUSE:
4217 decode_iei_radio_cause(ie, bi, org_offset);
4219 case BSSGP_IEI_RA_CAP_UPD_CAUSE:
4220 decode_iei_ra_cap_upd_cause(ie, bi, org_offset);
4222 case BSSGP_IEI_ROUTEING_AREA:
4223 decode_iei_routeing_area(ie, bi, org_offset);
4225 case BSSGP_IEI_R_DEFAULT_MS:
4226 decode_bucket_leak_rate(ie, bi, org_offset);
4228 case BSSGP_IEI_SUSPEND_REFERENCE_NUMBER:
4229 decode_simple_ie(ie, bi, org_offset, "", "", TRUE);
4232 decode_simple_ie(ie, bi, org_offset, "", "", TRUE);
4234 case BSSGP_IEI_TLLI:
4235 decode_iei_tlli(ie, bi, org_offset);
4237 case BSSGP_IEI_TMSI:
4238 decode_mobile_identity(ie, bi, org_offset);
4240 case BSSGP_IEI_TRACE_REFERENCE:
4241 decode_simple_ie(ie, bi, org_offset, "", "", TRUE);
4243 case BSSGP_IEI_TRACE_TYPE:
4244 /* XXX: Coding unknown (Specification withdrawn) 3GPP TS 32.008 */
4245 decode_simple_ie(ie, bi, org_offset, "", "", TRUE);
4247 case BSSGP_IEI_TRANSACTION_ID:
4248 decode_simple_ie(ie, bi, org_offset, "", "", TRUE);
4250 case BSSGP_IEI_TRIGGER_ID:
4251 decode_iei_trigger_id(ie, bi, org_offset);
4253 case BSSGP_IEI_NUMBER_OF_OCTETS_AFFECTED:
4254 decode_simple_ie(ie, bi, org_offset, "", "", TRUE);
4256 case BSSGP_IEI_LSA_IDENTIFIER_LIST:
4257 decode_iei_lsa_identifier_list(ie, bi, org_offset);
4259 case BSSGP_IEI_LSA_INFORMATION:
4260 decode_iei_lsa_information(ie, bi, org_offset);
4263 decode_pfi(ie, bi, org_offset);
4265 case BSSGP_IEI_GPRS_TIMER:
4266 decode_iei_gprs_timer(ie, bi, org_offset);
4268 case BSSGP_IEI_ABQP:
4269 decode_iei_abqp(ie, bi, org_offset);
4271 case BSSGP_IEI_FEATURE_BITMAP:
4272 decode_iei_feature_bitmap(ie, bi, org_offset);
4274 case BSSGP_IEI_BUCKET_FULL_RATIO:
4275 decode_iei_bucket_full_ratio(ie, bi, org_offset);
4277 case BSSGP_IEI_SERVICE_UTRAN_CCO:
4278 decode_iei_service_utran_cco(ie, bi, org_offset);
4280 case BSSGP_IEI_NSEI:
4281 decode_iei_nsei(ie, bi, org_offset);
4283 case BSSGP_IEI_RRLP_APDU:
4284 bssgp_proto_handoff(ie, bi, org_offset, rrlp_handle);
4286 case BSSGP_IEI_LCS_QOS:
4287 decode_iei_lcs_qos(ie, bi, org_offset);
4289 case BSSGP_IEI_LCS_CLIENT_TYPE:
4290 decode_iei_lcs_client_type(ie, bi, org_offset);
4292 case BSSGP_IEI_REQUESTED_GPS_ASSISTANCE_DATA:
4293 decode_iei_requested_gps_assistance_data(ie, bi, org_offset);
4295 case BSSGP_IEI_LOCATION_TYPE:
4296 decode_iei_location_type(ie, bi, org_offset);
4298 case BSSGP_IEI_LOCATION_ESTIMATE:
4299 decode_iei_location_estimate(ie, bi, org_offset);
4301 case BSSGP_IEI_POSITIONING_DATA:
4302 decode_iei_positioning_data(ie, bi, org_offset);
4304 case BSSGP_IEI_DECIPHERING_KEYS:
4305 decode_iei_deciphering_keys(ie, bi, org_offset);
4307 case BSSGP_IEI_LCS_PRIORITY:
4308 decode_iei_lcs_priority(ie, bi, org_offset);
4310 case BSSGP_IEI_LCS_CAUSE:
4311 decode_iei_lcs_cause(ie, bi, org_offset);
4313 case BSSGP_IEI_LCS_CAPABILITY:
4314 decode_iei_lcs_capability(ie, bi, org_offset);
4316 case BSSGP_IEI_RRLP_FLAGS:
4317 decode_iei_rrlp_flags(ie, bi, org_offset);
4319 case BSSGP_IEI_RIM_APPLICATION_IDENTITY:
4320 decode_iei_rim_application_identity(ie, bi, org_offset);
4322 case BSSGP_IEI_RIM_SEQUENCE_NUMBER:
4323 decode_simple_ie(ie, bi, org_offset, "", "", TRUE);
4325 case BSSGP_IEI_RAN_INFORMATION_REQUEST_CONTAINER_UNIT:
4326 decode_iei_ran_information_request_container_unit(ie, bi, org_offset);
4328 case BSSGP_IEI_RAN_INFORMATION_CONTAINER_UNIT:
4329 decode_iei_ran_information_container_unit(ie, bi, org_offset);
4331 case BSSGP_IEI_RAN_INFORMATION_INDICATIONS:
4332 decode_iei_ran_information_indications(ie, bi, org_offset);
4334 case BSSGP_IEI_NUMBER_OF_CONTAINER_UNITS:
4335 decode_iei_number_of_container_units(ie, bi, org_offset);
4337 case BSSGP_IEI_PFC_FLOW_CONTROL_PARAMETERS:
4338 decode_iei_pfc_flow_control_parameters(ie, bi, org_offset);
4340 case BSSGP_IEI_GLOBAL_CN_ID:
4341 decode_iei_global_cn_id(ie, bi, org_offset);
4346 if (use_default_ie_name) {
4347 /* Memory has been allocated; free it */
4354 decode_pdu_general(bssgp_ie_t *ies, int num_ies, build_info_t *bi) {
4356 for (i = 0; i < num_ies; i++) {
4357 decode_ie(&ies[i], bi);
4362 decode_pdu_dl_unitdata(build_info_t *bi) {
4363 bssgp_ie_t ies[] = {
4364 { BSSGP_IEI_TLLI, "TLLI (current)",
4365 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_V, BSSGP_UNKNOWN, 4 },
4367 { BSSGP_IEI_QOS_PROFILE, NULL,
4368 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_V, BSSGP_UNKNOWN, 3 },
4370 { BSSGP_IEI_PDU_LIFETIME, NULL,
4371 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4},
4373 { BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY, NULL,
4374 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN},
4376 { BSSGP_IEI_PRIORITY, NULL,
4377 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3},
4379 { BSSGP_IEI_DRX_PARAMETERS, NULL,
4380 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4},
4382 { BSSGP_IEI_IMSI, NULL,
4383 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN},
4385 { BSSGP_IEI_TLLI, "TLLI (old)",
4386 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6},
4388 { BSSGP_IEI_PFI, NULL,
4389 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3},
4391 { BSSGP_IEI_LSA_INFORMATION, NULL,
4392 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN},
4394 { BSSGP_IEI_SERVICE_UTRAN_CCO, NULL,
4395 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3},
4397 { BSSGP_IEI_ALIGNMENT_OCTETS, NULL,
4398 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN},
4400 { BSSGP_IEI_LLC_PDU, NULL,
4401 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN},
4404 bi->ul_data = FALSE;
4406 decode_pdu_general(ies, 13, bi);
4411 decode_pdu_ul_unitdata(build_info_t *bi) {
4412 bssgp_ie_t ies[] = {
4413 { BSSGP_IEI_TLLI, NULL,
4414 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_V, BSSGP_UNKNOWN, 4 },
4416 { BSSGP_IEI_QOS_PROFILE, NULL,
4417 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_V, BSSGP_UNKNOWN, 3 },
4419 { BSSGP_IEI_CELL_IDENTIFIER, NULL,
4420 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
4422 { BSSGP_IEI_PFI, NULL,
4423 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4425 { BSSGP_IEI_LSA_IDENTIFIER_LIST, NULL,
4426 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
4428 { BSSGP_IEI_ALIGNMENT_OCTETS, NULL,
4429 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
4431 { BSSGP_IEI_LLC_PDU, NULL,
4432 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
4434 bi->dl_data = FALSE;
4437 decode_pdu_general(ies, 7, bi);
4441 decode_pdu_ra_capability(build_info_t *bi) {
4442 bssgp_ie_t ies[] = {
4443 { BSSGP_IEI_TLLI, NULL,
4444 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4446 { BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY, NULL,
4447 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN},
4450 bi->ul_data = FALSE;
4452 decode_pdu_general(ies, 2, bi);
4456 decode_pdu_ptm_unitdata(build_info_t *bi) {
4457 proto_tree_add_text(bi->bssgp_tree, bi->tvb, bi->offset, -1,
4458 "This shall be developed in GPRS phase 2");
4462 decode_pdu_paging_ps(build_info_t *bi) {
4463 bssgp_ie_t ies[] = {
4464 { BSSGP_IEI_IMSI, NULL,
4465 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
4467 { BSSGP_IEI_DRX_PARAMETERS, NULL,
4468 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4470 { BSSGP_IEI_BVCI, NULL,
4471 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4473 { BSSGP_IEI_LOCATION_AREA, NULL,
4474 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 7 },
4476 { BSSGP_IEI_ROUTEING_AREA, NULL,
4477 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 },
4479 { BSSGP_IEI_BSS_AREA_INDICATION, NULL,
4480 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4482 { BSSGP_IEI_PFI, NULL,
4483 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4485 { BSSGP_IEI_ABQP, NULL,
4486 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
4488 { BSSGP_IEI_QOS_PROFILE, NULL,
4489 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 5 },
4491 { BSSGP_IEI_TMSI, "P-TMSI",
4492 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4495 bi->ul_data = FALSE;
4497 decode_pdu_general(ies, 10, bi);
4501 decode_pdu_paging_cs(build_info_t *bi) {
4502 bssgp_ie_t ies[] = {
4503 { BSSGP_IEI_IMSI, NULL,
4504 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
4506 { BSSGP_IEI_DRX_PARAMETERS, NULL,
4507 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4509 { BSSGP_IEI_BVCI, NULL,
4510 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4512 { BSSGP_IEI_LOCATION_AREA, NULL,
4513 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 7 },
4515 { BSSGP_IEI_ROUTEING_AREA, NULL,
4516 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 },
4518 { BSSGP_IEI_BSS_AREA_INDICATION, NULL,
4519 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4521 { BSSGP_IEI_TLLI, NULL,
4522 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4524 { BSSGP_IEI_CHANNEL_NEEDED, NULL,
4525 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4527 { BSSGP_IEI_EMLPP_PRIORITY, NULL,
4528 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4530 { BSSGP_IEI_TMSI, NULL,
4531 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4533 { BSSGP_IEI_GLOBAL_CN_ID, NULL,
4534 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 7 },
4537 bi->ul_data = FALSE;
4539 decode_pdu_general(ies, 11, bi);
4543 decode_pdu_ra_capability_update(build_info_t *bi) {
4544 bssgp_ie_t ies[] = {
4545 { BSSGP_IEI_TLLI, NULL,
4546 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4548 { BSSGP_IEI_TAG, NULL,
4549 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4551 bi->dl_data = FALSE;
4554 decode_pdu_general(ies, 2, bi);
4558 decode_pdu_ra_capability_update_ack(build_info_t *bi) {
4559 bssgp_ie_t ies[] = {
4560 { BSSGP_IEI_TLLI, NULL,
4561 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4563 { BSSGP_IEI_TAG, NULL,
4564 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4566 { BSSGP_IEI_IMSI, NULL,
4567 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
4569 { BSSGP_IEI_RA_CAP_UPD_CAUSE, NULL,
4570 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4572 { BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY, NULL,
4573 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN},
4576 bi->ul_data = FALSE;
4578 decode_pdu_general(ies, 5, bi);
4582 decode_pdu_radio_status(build_info_t *bi) {
4583 bssgp_ie_t ies[] = {
4584 { BSSGP_IEI_TLLI, NULL,
4585 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4587 { BSSGP_IEI_TMSI, NULL,
4588 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4590 { BSSGP_IEI_IMSI, NULL,
4591 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
4593 { BSSGP_IEI_RADIO_CAUSE, NULL,
4594 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4596 bi->dl_data = FALSE;
4599 decode_pdu_general(ies, 4, bi);
4603 decode_pdu_suspend(build_info_t *bi) {
4604 bssgp_ie_t ies[] = {
4605 { BSSGP_IEI_TLLI, NULL,
4606 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4608 { BSSGP_IEI_ROUTEING_AREA, NULL,
4609 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 },
4611 bi->dl_data = FALSE;
4614 decode_pdu_general(ies, 2, bi);
4618 decode_pdu_suspend_ack(build_info_t *bi) {
4619 bssgp_ie_t ies[] = {
4620 { BSSGP_IEI_TLLI, NULL,
4621 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4623 { BSSGP_IEI_ROUTEING_AREA, NULL,
4624 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 },
4626 { BSSGP_IEI_SUSPEND_REFERENCE_NUMBER, NULL,
4627 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4630 bi->ul_data = FALSE;
4632 decode_pdu_general(ies, 3, bi);
4636 decode_pdu_suspend_nack(build_info_t *bi) {
4637 bssgp_ie_t ies[] = {
4638 { BSSGP_IEI_TLLI, NULL,
4639 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4641 { BSSGP_IEI_ROUTEING_AREA, NULL,
4642 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 },
4644 { BSSGP_IEI_CAUSE, NULL,
4645 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4648 bi->ul_data = FALSE;
4650 decode_pdu_general(ies, 3, bi);
4654 decode_pdu_resume(build_info_t *bi) {
4655 bssgp_ie_t ies[] = {
4656 { BSSGP_IEI_TLLI, NULL,
4657 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4659 { BSSGP_IEI_ROUTEING_AREA, NULL,
4660 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 },
4662 { BSSGP_IEI_SUSPEND_REFERENCE_NUMBER, NULL,
4663 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4665 bi->dl_data = FALSE;
4668 decode_pdu_general(ies, 3, bi);
4672 decode_pdu_resume_ack(build_info_t *bi) {
4673 bssgp_ie_t ies[] = {
4674 { BSSGP_IEI_TLLI, NULL,
4675 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4677 { BSSGP_IEI_ROUTEING_AREA, NULL,
4678 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 },
4682 bi->ul_data = FALSE;
4684 decode_pdu_general(ies, 2, bi);
4688 decode_pdu_resume_nack(build_info_t *bi) {
4689 bssgp_ie_t ies[] = {
4690 { BSSGP_IEI_TLLI, NULL,
4691 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4693 { BSSGP_IEI_ROUTEING_AREA, NULL,
4694 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 },
4696 { BSSGP_IEI_CAUSE, NULL,
4697 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4700 bi->ul_data = FALSE;
4702 decode_pdu_general(ies, 3, bi);
4706 decode_pdu_bvc_block(build_info_t *bi) {
4707 bssgp_ie_t ies[] = {
4708 { BSSGP_IEI_BVCI, NULL,
4709 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4711 { BSSGP_IEI_CAUSE, NULL,
4712 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4714 bi->dl_data = FALSE;
4717 decode_pdu_general(ies, 2, bi);
4721 decode_pdu_bvc_block_ack(build_info_t *bi) {
4722 bssgp_ie_t ies[] = {
4723 { BSSGP_IEI_BVCI, NULL,
4724 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4},
4727 bi->ul_data = FALSE;
4729 decode_pdu_general(ies, 1, bi);
4733 decode_pdu_bvc_reset(build_info_t *bi) {
4734 bssgp_ie_t ies[] = {
4735 { BSSGP_IEI_BVCI, NULL,
4736 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4738 { BSSGP_IEI_CAUSE, NULL,
4739 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4741 { BSSGP_IEI_CELL_IDENTIFIER, NULL,
4742 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
4744 { BSSGP_IEI_FEATURE_BITMAP, NULL,
4745 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4750 decode_pdu_general(ies, 4, bi);
4754 decode_pdu_bvc_reset_ack(build_info_t *bi) {
4755 bssgp_ie_t ies[] = {
4756 { BSSGP_IEI_BVCI, NULL,
4757 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4759 { BSSGP_IEI_CELL_IDENTIFIER, NULL,
4760 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
4762 { BSSGP_IEI_FEATURE_BITMAP, NULL,
4763 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4768 decode_pdu_general(ies, 3, bi);
4772 decode_pdu_bvc_unblock(build_info_t *bi) {
4773 bssgp_ie_t ies[] = {
4774 { BSSGP_IEI_BVCI, NULL,
4775 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4777 bi->dl_data = FALSE;
4780 decode_pdu_general(ies, 1, bi);
4784 decode_pdu_bvc_unblock_ack(build_info_t *bi) {
4785 bssgp_ie_t ies[] = {
4786 { BSSGP_IEI_BVCI, NULL,
4787 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4790 bi->ul_data = FALSE;
4792 decode_pdu_general(ies, 1, bi);
4796 decode_pdu_flow_control_bvc(build_info_t *bi) {
4797 bssgp_ie_t ies[] = {
4798 { BSSGP_IEI_TAG, NULL,
4799 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4801 { BSSGP_IEI_BVC_BUCKET_SIZE, NULL,
4802 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4804 { BSSGP_IEI_BUCKET_LEAK_RATE, NULL,
4805 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4807 { BSSGP_IEI_BMAX_DEFAULT_MS, NULL,
4808 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4810 { BSSGP_IEI_R_DEFAULT_MS, NULL,
4811 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4813 { BSSGP_IEI_BUCKET_FULL_RATIO, NULL,
4814 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4816 { BSSGP_IEI_BVC_MEASUREMENT, NULL,
4817 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4819 bi->dl_data = FALSE;
4822 decode_pdu_general(ies, 7, bi);
4826 decode_pdu_flow_control_bvc_ack(build_info_t *bi) {
4827 bssgp_ie_t ies[] = {
4828 { BSSGP_IEI_TAG, NULL,
4829 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4832 bi->ul_data = FALSE;
4834 decode_pdu_general(ies, 1, bi);
4838 decode_pdu_flow_control_ms(build_info_t *bi) {
4839 bssgp_ie_t ies[] = {
4840 { BSSGP_IEI_TLLI, NULL,
4841 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4843 { BSSGP_IEI_TAG, NULL,
4844 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4846 { BSSGP_IEI_MS_BUCKET_SIZE, NULL,
4847 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4849 { BSSGP_IEI_BUCKET_LEAK_RATE, NULL,
4850 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4852 { BSSGP_IEI_BUCKET_FULL_RATIO, NULL,
4853 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4855 bi->dl_data = FALSE;
4858 decode_pdu_general(ies, 5, bi);
4862 decode_pdu_flow_control_ms_ack(build_info_t *bi) {
4863 bssgp_ie_t ies[] = {
4864 { BSSGP_IEI_TLLI, NULL,
4865 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4867 { BSSGP_IEI_TAG, NULL,
4868 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4871 bi->ul_data = FALSE;
4873 decode_pdu_general(ies, 2, bi);
4877 decode_pdu_flush_ll(build_info_t *bi) {
4878 bssgp_ie_t ies[] = {
4879 { BSSGP_IEI_TLLI, NULL,
4880 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4882 { BSSGP_IEI_BVCI, "BVCI (old)",
4883 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4885 { BSSGP_IEI_BVCI, "BVCI (new)",
4886 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4888 { BSSGP_IEI_NSEI, "NSEI (new)",
4889 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4892 bi->ul_data = FALSE;
4894 decode_pdu_general(ies, 4, bi);
4898 decode_pdu_flush_ll_ack(build_info_t *bi) {
4899 bssgp_ie_t ies[] = {
4900 { BSSGP_IEI_TLLI, NULL,
4901 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4903 { BSSGP_IEI_FLUSH_ACTION, NULL,
4904 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4906 { BSSGP_IEI_BVCI, "BVCI (new)",
4907 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4909 { BSSGP_IEI_NUMBER_OF_OCTETS_AFFECTED, NULL,
4910 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 5 },
4912 { BSSGP_IEI_NSEI, "NSEI (new)",
4913 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4915 bi->dl_data = FALSE;
4918 decode_pdu_general(ies, 5, bi);
4922 decode_pdu_llc_discarded(build_info_t *bi) {
4923 bssgp_ie_t ies[] = {
4924 { BSSGP_IEI_TLLI, NULL,
4925 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4927 { BSSGP_IEI_LLC_FRAMES_DISCARDED, NULL,
4928 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4930 { BSSGP_IEI_BVCI, NULL,
4931 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4933 { BSSGP_IEI_NUMBER_OF_OCTETS_AFFECTED, "Number of octets deleted",
4934 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 5 },
4936 { BSSGP_IEI_PFI, NULL,
4937 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4939 bi->dl_data = FALSE;
4942 decode_pdu_general(ies, 5, bi);
4946 decode_pdu_flow_control_pfc(build_info_t *bi) {
4947 bssgp_ie_t ies[] = {
4948 { BSSGP_IEI_TLLI, NULL,
4949 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4951 { BSSGP_IEI_TAG, NULL,
4952 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4954 { BSSGP_IEI_MS_BUCKET_SIZE, NULL,
4955 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4957 { BSSGP_IEI_BUCKET_LEAK_RATE, NULL,
4958 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4960 { BSSGP_IEI_BUCKET_FULL_RATIO, NULL,
4961 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4963 { BSSGP_IEI_PFC_FLOW_CONTROL_PARAMETERS, NULL,
4964 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
4966 bi->dl_data = FALSE;
4969 decode_pdu_general(ies, 6, bi);
4973 decode_pdu_flow_control_pfc_ack(build_info_t *bi) {
4974 bssgp_ie_t ies[] = {
4975 { BSSGP_IEI_TLLI, NULL,
4976 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
4978 { BSSGP_IEI_TAG, NULL,
4979 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4982 bi->ul_data = FALSE;
4984 decode_pdu_general(ies, 2, bi);
4988 decode_pdu_sgsn_invoke_trace(build_info_t *bi) {
4989 bssgp_ie_t ies[] = {
4990 { BSSGP_IEI_TRACE_TYPE, NULL,
4991 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
4993 { BSSGP_IEI_TRACE_REFERENCE, NULL,
4994 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
4996 { BSSGP_IEI_TRIGGER_ID, NULL,
4997 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
4999 { BSSGP_IEI_MOBILE_ID, NULL,
5000 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5002 { BSSGP_IEI_OMC_ID, NULL,
5003 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5005 { BSSGP_IEI_TRANSACTION_ID, NULL,
5006 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5009 bi->ul_data = FALSE;
5011 decode_pdu_general(ies, 6, bi);
5015 decode_pdu_status(build_info_t *bi) {
5016 bssgp_ie_t ies[] = {
5017 { BSSGP_IEI_CAUSE, NULL,
5018 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5020 { BSSGP_IEI_BVCI, NULL,
5021 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5023 { BSSGP_IEI_PDU_IN_ERROR, NULL,
5024 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5029 decode_pdu_general(ies, 3, bi);
5033 decode_pdu_download_bss_pfc(build_info_t *bi) {
5034 bssgp_ie_t ies[] = {
5035 { BSSGP_IEI_TLLI, NULL,
5036 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5038 { BSSGP_IEI_PFI, NULL,
5039 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5041 bi->dl_data = FALSE;
5044 decode_pdu_general(ies, 2, bi);
5048 decode_pdu_create_bss_pfc(build_info_t *bi) {
5049 bssgp_ie_t ies[] = {
5050 { BSSGP_IEI_TLLI, NULL,
5051 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5053 { BSSGP_IEI_IMSI, NULL,
5054 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5056 { BSSGP_IEI_PFI, NULL,
5057 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5059 { BSSGP_IEI_GPRS_TIMER, "PFT",
5060 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5062 { BSSGP_IEI_ABQP, NULL,
5063 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5065 { BSSGP_IEI_SERVICE_UTRAN_CCO, NULL,
5066 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5068 { BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY, NULL,
5069 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5071 { BSSGP_IEI_PRIORITY, "Allocation/Retention Priority",
5072 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5074 { BSSGP_IEI_GPRS_TIMER, "T10",
5075 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5078 bi->ul_data = FALSE;
5080 decode_pdu_general(ies, 9, bi);
5084 decode_pdu_create_bss_pfc_ack(build_info_t *bi) {
5085 bssgp_ie_t ies[] = {
5086 { BSSGP_IEI_TLLI, NULL,
5087 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5089 { BSSGP_IEI_PFI, NULL,
5090 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5092 { BSSGP_IEI_ABQP, NULL,
5093 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5095 { BSSGP_IEI_CAUSE, NULL,
5096 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5098 bi->dl_data = FALSE;
5101 decode_pdu_general(ies, 4, bi);
5105 decode_pdu_create_bss_pfc_nack(build_info_t *bi) {
5106 bssgp_ie_t ies[] = {
5107 { BSSGP_IEI_TLLI, NULL,
5108 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5110 { BSSGP_IEI_PFI, NULL,
5111 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5113 { BSSGP_IEI_CAUSE, NULL,
5114 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5116 bi->dl_data = FALSE;
5119 decode_pdu_general(ies, 3, bi);
5123 decode_pdu_modify_bss_pfc(build_info_t *bi) {
5124 bssgp_ie_t ies[] = {
5125 { BSSGP_IEI_TLLI, NULL,
5126 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5128 { BSSGP_IEI_PFI, NULL,
5129 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5131 { BSSGP_IEI_ABQP, NULL,
5132 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5134 bi->dl_data = FALSE;
5137 decode_pdu_general(ies, 3, bi);
5141 decode_pdu_modify_bss_pfc_ack(build_info_t *bi) {
5142 bssgp_ie_t ies[] = {
5143 { BSSGP_IEI_TLLI, NULL,
5144 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5146 { BSSGP_IEI_PFI, NULL,
5147 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5149 { BSSGP_IEI_GPRS_TIMER, "PFT",
5150 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5152 { BSSGP_IEI_ABQP, NULL,
5153 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5156 bi->ul_data = FALSE;
5158 decode_pdu_general(ies, 4, bi);
5162 decode_pdu_delete_bss_pfc(build_info_t *bi) {
5163 bssgp_ie_t ies[] = {
5164 { BSSGP_IEI_TLLI, NULL,
5165 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5167 { BSSGP_IEI_PFI, NULL,
5168 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5171 bi->ul_data = FALSE;
5173 decode_pdu_general(ies, 2, bi);
5177 decode_pdu_delete_bss_pfc_ack(build_info_t *bi) {
5178 bssgp_ie_t ies[] = {
5179 { BSSGP_IEI_TLLI, NULL,
5180 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5182 { BSSGP_IEI_PFI, NULL,
5183 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5185 bi->dl_data = FALSE;
5188 decode_pdu_general(ies, 2, bi);
5192 decode_pdu_delete_bss_pfc_req(build_info_t *bi) {
5193 bssgp_ie_t ies[] = {
5194 { BSSGP_IEI_TLLI, NULL,
5195 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5197 { BSSGP_IEI_PFI, NULL,
5198 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5200 { BSSGP_IEI_CAUSE, NULL,
5201 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5203 bi->dl_data = FALSE;
5206 decode_pdu_general(ies, 3, bi);
5210 decode_pdu_perform_location_request(build_info_t *bi) {
5211 bssgp_ie_t ies[] = {
5212 { BSSGP_IEI_TLLI, NULL,
5213 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5215 { BSSGP_IEI_IMSI, NULL,
5216 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5218 { BSSGP_IEI_DRX_PARAMETERS, NULL,
5219 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5221 { BSSGP_IEI_BVCI, "BVCI (PCU-PTP)",
5222 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5224 { BSSGP_IEI_NSEI, "NSEI (PCU-PTP)",
5225 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5227 { BSSGP_IEI_LOCATION_TYPE, NULL,
5228 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5230 { BSSGP_IEI_CELL_IDENTIFIER, NULL,
5231 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5233 { BSSGP_IEI_LCS_CAPABILITY, NULL,
5234 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5236 { BSSGP_IEI_LCS_PRIORITY, NULL,
5237 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5239 { BSSGP_IEI_LCS_QOS, NULL,
5240 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5242 { BSSGP_IEI_LCS_CLIENT_TYPE, NULL,
5243 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5245 { BSSGP_IEI_REQUESTED_GPS_ASSISTANCE_DATA, NULL,
5246 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5249 bi->ul_data = FALSE;
5251 decode_pdu_general(ies, 12, bi);
5255 decode_pdu_perform_location_response(build_info_t *bi) {
5256 bssgp_ie_t ies[] = {
5257 { BSSGP_IEI_TLLI, NULL,
5258 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5260 { BSSGP_IEI_BVCI, "BVCI (PCU-PTP)",
5261 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5263 { BSSGP_IEI_LOCATION_ESTIMATE, NULL,
5264 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5266 { BSSGP_IEI_POSITIONING_DATA, NULL,
5267 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5269 { BSSGP_IEI_DECIPHERING_KEYS, NULL,
5270 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5272 { BSSGP_IEI_LCS_CAUSE, NULL,
5273 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5275 bi->dl_data = FALSE;
5278 decode_pdu_general(ies, 6, bi);
5282 decode_pdu_perform_location_abort(build_info_t *bi) {
5283 bssgp_ie_t ies[] = {
5284 { BSSGP_IEI_TLLI, NULL,
5285 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5287 { BSSGP_IEI_BVCI, "BVCI (PCU-PTP)",
5288 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5290 { BSSGP_IEI_LCS_CAUSE, NULL,
5291 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5294 bi->ul_data = FALSE;
5296 decode_pdu_general(ies, 3, bi);
5300 decode_pdu_position_command(build_info_t *bi) {
5301 bssgp_ie_t ies[] = {
5302 { BSSGP_IEI_TLLI, NULL,
5303 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5305 { BSSGP_IEI_BVCI, "BVCI (PCU-PTP)",
5306 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5308 { BSSGP_IEI_RRLP_FLAGS, NULL,
5309 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5311 { BSSGP_IEI_RRLP_APDU, NULL,
5312 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5314 bi->dl_data = FALSE;
5317 decode_pdu_general(ies, 4, bi);
5321 decode_pdu_position_response(build_info_t *bi) {
5322 bssgp_ie_t ies[] = {
5323 { BSSGP_IEI_TLLI, NULL,
5324 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 },
5326 { BSSGP_IEI_BVCI, "BVCI (PCU-PTP)",
5327 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5329 { BSSGP_IEI_RRLP_FLAGS, NULL,
5330 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5332 { BSSGP_IEI_RRLP_APDU, NULL,
5333 BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5335 { BSSGP_IEI_LCS_CAUSE, NULL,
5336 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5339 bi->ul_data = FALSE;
5341 decode_pdu_general(ies, 5, bi);
5346 decode_pdu_ran_information(build_info_t *bi) {
5347 bssgp_ie_t ies[] = {
5348 { BSSGP_IEI_CELL_IDENTIFIER, "Destination Cell identifier",
5349 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5351 { BSSGP_IEI_CELL_IDENTIFIER, "Source Cell Identifier",
5352 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5354 { BSSGP_IEI_RIM_APPLICATION_IDENTITY, NULL,
5355 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5357 { BSSGP_IEI_RIM_SEQUENCE_NUMBER, "Sequence Number",
5358 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5360 { BSSGP_IEI_RAN_INFORMATION_INDICATIONS, NULL,
5361 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5363 { BSSGP_IEI_CAUSE, "RIM Cause",
5364 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5366 { BSSGP_IEI_NUMBER_OF_CONTAINER_UNITS, NULL,
5367 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5369 { BSSGP_IEI_RAN_INFORMATION_CONTAINER_UNIT, "Container Unit",
5370 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5375 decode_pdu_general(ies, 7, bi);
5377 while (tvb_length_remaining(bi->tvb, bi->offset) >= 4) {
5378 guint32 org_offset = bi->offset;
5380 decode_ie(&ies[7], bi);
5382 /* prevent an endless loop */
5383 if(org_offset == bi->offset) {
5384 THROW(ReportedBoundsError);
5390 decode_pdu_ran_information_request(build_info_t *bi) {
5391 const guint8 MASK_EVENT_MR = 0x01;
5394 bssgp_ie_t ies[] = {
5395 { BSSGP_IEI_CELL_IDENTIFIER, "Destination Cell Identifier",
5396 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5398 { BSSGP_IEI_CELL_IDENTIFIER, "Source Cell Identifier",
5399 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5401 { BSSGP_IEI_RIM_APPLICATION_IDENTITY, NULL,
5402 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5404 { BSSGP_IEI_RIM_SEQUENCE_NUMBER, "Sequence Number",
5405 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5407 { BSSGP_IEI_RAN_INFORMATION_REQUEST_INDICATIONS, NULL,
5408 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5410 { BSSGP_IEI_RAN_INFORMATION_REQUEST_CONTAINER_UNIT, "Container Unit",
5411 BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5417 decode_pdu_general(ies, 4, bi);
5419 /* Account for type and length; assume length field = 1 as total length = 3: */
5421 if (bi->bssgp_tree) {
5422 value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_EVENT_MR);
5423 proto_tree_add_text(bi->bssgp_tree, bi->tvb, bi->offset - 2, 3,
5424 "RAN Information Request Indications: Event MR = %u: %s-driven multiple reports requested",
5426 value == 0 ? "No event" : "Event");
5429 decode_pdu_general(&ies[5], 1, bi);
5433 decode_pdu_ran_information_ack(build_info_t *bi) {
5434 bssgp_ie_t ies[] = {
5435 { BSSGP_IEI_CELL_IDENTIFIER, "Destination Cell Identifier",
5436 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5438 { BSSGP_IEI_CELL_IDENTIFIER, "Source Cell Identifier",
5439 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5441 { BSSGP_IEI_RIM_APPLICATION_IDENTITY, NULL,
5442 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5444 { BSSGP_IEI_RIM_SEQUENCE_NUMBER, "Sequence Number",
5445 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 },
5450 decode_pdu_general(ies, 4, bi);
5454 decode_pdu_ran_information_error(build_info_t *bi) {
5455 bssgp_ie_t ies[] = {
5456 { BSSGP_IEI_CELL_IDENTIFIER, "Destination Cell Identifier",
5457 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5459 { BSSGP_IEI_CELL_IDENTIFIER, "Source Cell Identifier",
5460 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 },
5462 { BSSGP_IEI_RIM_APPLICATION_IDENTITY, NULL,
5463 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5465 { BSSGP_IEI_CAUSE, "RIM Cause",
5466 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 },
5468 { BSSGP_IEI_PDU_IN_ERROR, NULL,
5469 BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN },
5474 decode_pdu_general(ies, 5, bi);
5478 decode_pdu(guint8 pdutype, build_info_t *bi) {
5481 case BSSGP_PDU_DL_UNITDATA:
5482 decode_pdu_dl_unitdata(bi);
5484 case BSSGP_PDU_UL_UNITDATA:
5485 decode_pdu_ul_unitdata(bi);
5487 case BSSGP_PDU_RA_CAPABILITY:
5488 decode_pdu_ra_capability(bi);
5490 case BSSGP_PDU_PTM_UNITDATA:
5491 decode_pdu_ptm_unitdata(bi);
5493 case BSSGP_PDU_PAGING_PS:
5494 decode_pdu_paging_ps(bi);
5496 case BSSGP_PDU_PAGING_CS:
5497 decode_pdu_paging_cs(bi);
5499 case BSSGP_PDU_RA_CAPABILITY_UPDATE:
5500 decode_pdu_ra_capability_update(bi);
5502 case BSSGP_PDU_RA_CAPABILITY_UPDATE_ACK:
5503 decode_pdu_ra_capability_update_ack(bi);
5505 case BSSGP_PDU_RADIO_STATUS:
5506 decode_pdu_radio_status(bi);
5508 case BSSGP_PDU_SUSPEND:
5509 decode_pdu_suspend(bi);
5511 case BSSGP_PDU_SUSPEND_ACK:
5512 decode_pdu_suspend_ack(bi);
5514 case BSSGP_PDU_SUSPEND_NACK:
5515 decode_pdu_suspend_nack(bi);
5517 case BSSGP_PDU_RESUME:
5518 decode_pdu_resume(bi);
5520 case BSSGP_PDU_RESUME_ACK:
5521 decode_pdu_resume_ack(bi);
5523 case BSSGP_PDU_RESUME_NACK:
5524 decode_pdu_resume_nack(bi);
5526 case BSSGP_PDU_BVC_BLOCK:
5527 decode_pdu_bvc_block(bi);
5529 case BSSGP_PDU_BVC_BLOCK_ACK:
5530 decode_pdu_bvc_block_ack(bi);
5532 case BSSGP_PDU_BVC_RESET:
5533 decode_pdu_bvc_reset(bi);
5535 case BSSGP_PDU_BVC_RESET_ACK:
5536 decode_pdu_bvc_reset_ack(bi);
5538 case BSSGP_PDU_BVC_UNBLOCK:
5539 decode_pdu_bvc_unblock(bi);
5541 case BSSGP_PDU_BVC_UNBLOCK_ACK:
5542 decode_pdu_bvc_unblock_ack(bi);
5544 case BSSGP_PDU_FLOW_CONTROL_BVC:
5545 decode_pdu_flow_control_bvc(bi);
5547 case BSSGP_PDU_FLOW_CONTROL_BVC_ACK:
5548 decode_pdu_flow_control_bvc_ack(bi);
5550 case BSSGP_PDU_FLOW_CONTROL_MS:
5551 decode_pdu_flow_control_ms(bi);
5553 case BSSGP_PDU_FLOW_CONTROL_MS_ACK:
5554 decode_pdu_flow_control_ms_ack(bi);
5556 case BSSGP_PDU_FLUSH_LL:
5557 decode_pdu_flush_ll(bi);
5559 case BSSGP_PDU_FLUSH_LL_ACK:
5560 decode_pdu_flush_ll_ack(bi);
5562 case BSSGP_PDU_LLC_DISCARDED:
5563 decode_pdu_llc_discarded(bi);
5565 case BSSGP_PDU_FLOW_CONTROL_PFC:
5566 decode_pdu_flow_control_pfc(bi);
5568 case BSSGP_PDU_FLOW_CONTROL_PFC_ACK:
5569 decode_pdu_flow_control_pfc_ack(bi);
5571 case BSSGP_PDU_SGSN_INVOKE_TRACE:
5572 decode_pdu_sgsn_invoke_trace(bi);
5574 case BSSGP_PDU_STATUS:
5575 decode_pdu_status(bi);
5577 case BSSGP_PDU_DOWNLOAD_BSS_PFC:
5578 decode_pdu_download_bss_pfc(bi);
5580 case BSSGP_PDU_CREATE_BSS_PFC:
5581 decode_pdu_create_bss_pfc(bi);
5583 case BSSGP_PDU_CREATE_BSS_PFC_ACK:
5584 decode_pdu_create_bss_pfc_ack(bi);
5586 case BSSGP_PDU_CREATE_BSS_PFC_NACK:
5587 decode_pdu_create_bss_pfc_nack(bi);
5589 case BSSGP_PDU_MODIFY_BSS_PFC:
5590 decode_pdu_modify_bss_pfc(bi);
5592 case BSSGP_PDU_MODIFY_BSS_PFC_ACK:
5593 decode_pdu_modify_bss_pfc_ack(bi);
5595 case BSSGP_PDU_DELETE_BSS_PFC:
5596 decode_pdu_delete_bss_pfc(bi);
5598 case BSSGP_PDU_DELETE_BSS_PFC_ACK:
5599 decode_pdu_delete_bss_pfc_ack(bi);
5601 case BSSGP_PDU_DELETE_BSS_PFC_REQ:
5602 decode_pdu_delete_bss_pfc_req(bi);
5604 case BSSGP_PDU_PERFORM_LOCATION_REQUEST:
5605 decode_pdu_perform_location_request(bi);
5607 case BSSGP_PDU_PERFORM_LOCATION_RESPONSE:
5608 decode_pdu_perform_location_response(bi);
5610 case BSSGP_PDU_PERFORM_LOCATION_ABORT:
5611 decode_pdu_perform_location_abort(bi);
5613 case BSSGP_PDU_POSITION_COMMAND:
5614 decode_pdu_position_command(bi);
5616 case BSSGP_PDU_POSITION_RESPONSE:
5617 decode_pdu_position_response(bi);
5619 case BSSGP_PDU_RAN_INFORMATION:
5620 decode_pdu_ran_information(bi);
5622 case BSSGP_PDU_RAN_INFORMATION_REQUEST:
5623 decode_pdu_ran_information_request(bi);
5625 case BSSGP_PDU_RAN_INFORMATION_ACK:
5626 decode_pdu_ran_information_ack(bi);
5628 case BSSGP_PDU_RAN_INFORMATION_ERROR:
5629 decode_pdu_ran_information_error(bi);
5637 dissect_bssgp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5640 build_info_t bi = { NULL, 0, NULL, NULL, NULL, FALSE, FALSE };
5643 proto_tree *bssgp_tree;
5647 bi.parent_tree = tree;
5649 pinfo->current_proto = "BSSGP";
5651 if (check_col(pinfo->cinfo, COL_PROTOCOL))
5652 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BSSGP");
5654 if (check_col(pinfo->cinfo, COL_INFO))
5655 col_clear(pinfo->cinfo, COL_INFO);
5657 pdutype = tvb_get_guint8(tvb, 0);
5661 ti = proto_tree_add_item(tree, proto_bssgp, tvb, 0, -1, FALSE);
5662 bssgp_tree = proto_item_add_subtree(ti, ett_bssgp);
5663 proto_tree_add_uint_format(bssgp_tree, hf_bssgp_pdu_type, tvb, 0, 1,
5665 "PDU Type: %s (%#02x)",
5666 val_to_str(pdutype, tab_bssgp_pdu_types,
5667 "Unknown"), pdutype);
5668 bi.bssgp_tree = bssgp_tree;
5671 if (check_col(pinfo->cinfo, COL_INFO)) {
5672 col_add_str(pinfo->cinfo, COL_INFO, val_to_str(pdutype,
5673 tab_bssgp_pdu_types,
5674 "Unknown PDU type"));
5676 decode_pdu(pdutype, &bi);
5680 proto_register_bssgp(void)
5682 static hf_register_info hf[] = {
5683 { &hf_bssgp_pdu_type,
5684 { "PDU Type", "bssgp.pdu_type",
5685 FT_UINT8, BASE_HEX, VALS(tab_bssgp_pdu_types), 0x0,
5688 { &hf_bssgp_ie_type,
5689 { "IE Type", "bssgp.ie_type",
5690 FT_UINT8, BASE_HEX, VALS(tab_bssgp_ie_types), 0x0,
5691 "Information element type", HFILL }
5694 { "BVCI", "bssgp.bvci",
5695 FT_UINT16, BASE_HEX, NULL, 0x0,
5699 { "TLLI", "bssgp.tlli",
5700 FT_UINT32, BASE_HEX, NULL, 0x0,
5704 { "NSEI", "bssgp.nsei",
5705 FT_UINT16, BASE_HEX, NULL, 0x0,
5709 { "MCC", "bssgp.mcc",
5710 FT_UINT8, BASE_DEC, NULL, 0x0,
5714 { "MNC", "bssgp.mnc",
5715 FT_UINT8, BASE_DEC, NULL, 0x0,
5719 { "LAC", "bssgp.lac",
5720 FT_UINT16, BASE_DEC, NULL, 0x0,
5724 { "RAC", "bssgp.rac",
5725 FT_UINT8, BASE_DEC, NULL, 0x0,
5730 FT_UINT16, BASE_DEC, NULL, 0x0,
5731 "Cell Identity", HFILL }
5733 { &hf_bssgp_tmsi_ptmsi,
5734 { "TMSI/PTMSI", "bssgp.tmsi_ptmsi",
5735 FT_UINT32, BASE_HEX, NULL, 0x0,
5739 { "IMSI", "bssgp.imsi",
5740 FT_STRING, BASE_NONE, NULL, 0x0,
5744 { "IMEI", "bssgp.imei",
5745 FT_STRING, BASE_NONE, NULL, 0x0,
5749 { "IMEISV", "bssgp.imeisv",
5750 FT_STRING, BASE_NONE, NULL, 0x0,
5754 { "NRI", "bssgp.nri",
5755 FT_UINT16, BASE_DEC, NULL, 0x0,
5760 /* Setup protocol subtree array */
5761 static gint *ett[] = {
5763 &ett_bssgp_qos_profile,
5764 &ett_bssgp_gprs_timer,
5765 &ett_bssgp_cell_identifier,
5766 &ett_bssgp_channel_needed,
5767 &ett_bssgp_drx_parameters,
5768 &ett_bssgp_mobile_identity,
5769 &ett_bssgp_priority,
5770 &ett_bssgp_lsa_identifier_list,
5771 &ett_bssgp_lsa_information,
5772 &ett_bssgp_lsa_information_lsa_identification_and_attributes,
5775 &ett_bssgp_lcs_client_type,
5776 &ett_bssgp_requested_gps_assistance_data,
5777 &ett_bssgp_requested_gps_assistance_data_satellite,
5778 &ett_bssgp_location_type,
5779 &ett_bssgp_positioning_data_positioning_method,
5780 &ett_bssgp_lcs_cause,
5781 &ett_bssgp_lcs_capability,
5782 &ett_bssgp_rrlp_flags,
5783 &ett_bssgp_ran_information_indications,
5786 &ett_bssgp_routeing_area,
5787 &ett_bssgp_location_area,
5789 &ett_bssgp_ran_information_request_container_unit,
5790 &ett_bssgp_ran_information_container_unit,
5791 &ett_bssgp_pfc_flow_control_parameters,
5792 &ett_bssgp_pfc_flow_control_parameters_pfc,
5793 &ett_bssgp_global_cn_id,
5794 &ett_bssgp_ms_radio_access_capability,
5795 &ett_bssgp_feature_bitmap,
5796 &ett_bssgp_positioning_data,
5797 &ett_bssgp_msrac_value_part,
5798 &ett_bssgp_msrac_additional_access_technologies,
5799 &ett_bssgp_msrac_access_capabilities,
5800 &ett_bssgp_msrac_a5_bits,
5801 &ett_bssgp_msrac_multislot_capability,
5805 /* Register the protocol name and description */
5806 proto_bssgp = proto_register_protocol("Base Station Subsystem GPRS Protocol", "BSSGP", "bssgp");
5808 /* Required function calls to register the header fields and subtrees used */
5809 proto_register_field_array(proto_bssgp, hf, array_length(hf));
5810 proto_register_subtree_array(ett, array_length(ett));
5811 register_dissector("bssgp", dissect_bssgp, proto_bssgp);
5813 /* Register configuration options */
5814 bssgp_module = prefs_register_protocol(proto_bssgp, proto_reg_handoff_bssgp);
5815 prefs_register_bool_preference(bssgp_module, "decode_nri",
5817 "Decode NRI (for use with SGSN in Pool)",
5819 prefs_register_uint_preference(bssgp_module, "nri_length", "NRI length",
5820 "NRI length, in bits",
5821 10, &bssgp_nri_length);
5824 /* If this dissector uses sub-dissector registration add a registration routine.
5827 proto_reg_handoff_bssgp(void)
5829 bssgp_handle = create_dissector_handle(dissect_bssgp, proto_bssgp);
5830 llc_handle = find_dissector("llcgprs");
5831 rrlp_handle = find_dissector("rrlp");
5832 data_handle = find_dissector("data");