Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-gsm_cbsp.c
blobbbfb0c99bf0bb38a5fab7e8319b7532b1ae28b2b
1 /* packet-gsm_cbsp.c
2 * Dissector for GSM / 3GPP TS 48.049 Cell Broadcast Service Protocol (CBSP)
4 * (C) 2018-2019 by Harald Welte <laforge@gnumonks.org>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include "config.h"
16 #include <epan/packet.h>
17 #include <epan/conversation.h>
18 #include <epan/asn1.h>
20 #include "packet-e164.h"
21 #include "packet-e212.h"
22 #include "packet-gsm_map.h"
23 #include "packet-cell_broadcast.h"
24 #include "packet-tcp.h" // tcp_dissect_pdus()
26 #define FRAME_HEADER_LEN 4
28 /***********************************************************************
29 * TLV related definitions
30 ***********************************************************************/
32 /*! Entry in a TLV parser array */
33 struct tlv_p_entry {
34 uint16_t len; /*!< length */
35 const uint8_t *val; /*!< pointer to value */
38 /*! TLV type */
39 enum tlv_type {
40 TLV_TYPE_NONE, /*!< no type */
41 TLV_TYPE_FIXED, /*!< fixed-length value-only */
42 TLV_TYPE_TV, /*!< tag-value (8bit) */
43 TLV_TYPE_TLV, /*!< tag-length-value */
44 TLV_TYPE_TL16V, /*!< tag, 16 bit length, value */
47 /*! Definition of a single IE (Information Element) */
48 struct tlv_def {
49 enum tlv_type type; /*!< TLV type */
50 uint8_t fixed_len; /*!< length in case of TLV_TYPE_FIXED */
53 /*! Definition of All 256 IE / TLV */
54 struct tlv_definition {
55 struct tlv_def def[256];
59 /***********************************************************************
60 * CBSP Protocol Definitions, see libosmocore/include/gsm/protocol/gsm_48_049.h
61 ***********************************************************************/
63 #define CBSP_TCP_PORT 48049
65 /* 8.2.1 Information Element Identifiers */
66 enum cbsp_iei {
67 CBSP_IEI_MSG_CONTENT = 0x01,
68 CBSP_IEI_OLD_SERIAL_NR = 0x02,
69 CBSP_IEI_NEW_SERIAL_NR = 0x03,
70 CBSP_IEI_CELL_LIST = 0x04,
71 CBSP_IEI_CATEGORY = 0x05,
72 CBSP_IEI_REP_PERIOD = 0x06,
73 CBSP_IEI_NUM_BCAST_REQ = 0x07,
74 CBSP_IEI_NUM_BCAST_COMPL_LIST = 0x08,
75 CBSP_IEI_FAILURE_LIST = 0x09,
76 CBSP_IEI_RR_LOADING_LIST = 0x0a,
77 CBSP_IEI_CAUSE = 0x0b,
78 CBSP_IEI_DCS = 0x0c,
79 CBSP_IEI_RECOVERY_IND = 0x0d,
80 CBSP_IEI_MSG_ID = 0x0e,
81 CBSP_IEI_EMERG_IND = 0x0f,
82 CBSP_IEI_WARN_TYPE = 0x10,
83 CBSP_IEI_WARN_SEC_INFO = 0x11,
84 CBSP_IEI_CHANNEL_IND = 0x12,
85 CBSP_IEI_NUM_OF_PAGES = 0x13,
86 CBSP_IEI_SCHEDULE_PERIOD = 0x14,
87 CBSP_IEI_NUM_OF_RES_SLOTS = 0x15,
88 CBSP_IEI_BCAST_MSG_TYPE = 0x16,
89 CBSP_IEI_WARNING_PERIOD = 0x17,
90 CBSP_IEI_KEEP_ALIVE_REP_PERIOD = 0x18,
93 /* 8.2.2 Message Type */
94 enum cbsp_msg_type {
95 CBSP_MSGT_WRITE_REPLACE = 0x01,
96 CBSP_MSGT_WRITE_REPLACE_COMPL = 0x02,
97 CBSP_MSGT_WRITE_REPLACE_FAIL = 0x03,
98 CBSP_MSGT_KILL = 0x04,
99 CBSP_MSGT_KILL_COMPL = 0x05,
100 CBSP_MSGT_KILL_FAIL = 0x06,
101 CBSP_MSGT_LOAD_QUERY = 0x07,
102 CBSP_MSGT_LOAD_QUERY_COMPL = 0x08,
103 CBSP_MSGT_LOAD_QUERY_FAIL = 0x09,
104 CBSP_MSGT_MSG_STATUS_QUERY = 0x0a,
105 CBSP_MSGT_MSG_STATUS_QUERY_COMPL= 0x0b,
106 CBSP_MSGT_MSG_STATUS_QUERY_FAIL = 0x0c,
107 CBSP_MSGT_SET_DRX = 0x0d,
108 CBSP_MSGT_SET_DRX_COMPL = 0x0e,
109 CBSP_MSGT_SET_DRX_FAIL = 0x0f,
110 CBSP_MSGT_RESET = 0x10,
111 CBSP_MSGT_RESET_COMPL = 0x11,
112 CBSP_MSGT_RESET_FAIL = 0x12,
113 CBSP_MSGT_RESTART = 0x13,
114 CBSP_MSGT_FAILURE = 0x14,
115 CBSP_MSGT_ERROR_IND = 0x15,
116 CBSP_MSGT_KEEP_ALIVE = 0x16,
117 CBSP_MSGT_KEEP_ALIVE_COMPL = 0x17,
120 /* 8.2.7 Category */
121 enum cbsp_category {
122 CBSP_CATEG_HIGH_PRIO = 0x00,
123 CBSP_CATEG_BACKGROUND = 0x01,
124 CBSP_CATEG_NORMAL = 0x02,
127 /* 8.2.9 Number of Broadcast Info */
128 enum cbsp_num_bcast_info {
129 CBSP_NUM_BCAST_INFO_VALID = 0x0,
130 CBSP_NUM_BCAST_INFO_OVERFLOW = 0x1,
131 CBSP_NUM_BCAST_INFO_UNKNOWN = 0x2,
134 static const value_string cbsp_num_bcast_info_vals[] = {
135 { CBSP_NUM_BCAST_INFO_VALID, "Number of Broadcasts Complete is Valid" },
136 { CBSP_NUM_BCAST_INFO_OVERFLOW, "Number of Broadcasts Complete has Overflown" },
137 { CBSP_NUM_BCAST_INFO_UNKNOWN, "Number of Broadcasts Complete is undefined" },
138 { 0, NULL }
141 static const value_string cbsp_num_bcast_shortinfo_vals[] = {
142 { CBSP_NUM_BCAST_INFO_VALID, "Valid" },
143 { CBSP_NUM_BCAST_INFO_OVERFLOW, "Overflow" },
144 { CBSP_NUM_BCAST_INFO_UNKNOWN, "Unknown" },
145 { 0, NULL }
148 /* Cell ID Discriminator (8.2.11, ...) */
149 enum cbsp_cell_id_disc {
150 CBSP_CIDD_WHOLE_CGI = 0x0,
151 CBSP_CIDD_LAC_CI = 0x1,
152 CBSP_CIDD_CI = 0x2,
153 CBSP_CIDD_LAI = 0x4,
154 CBSP_CIDD_LAC = 0x5,
155 CBSP_CIDD_ALL_IN_BSC = 0x6,
158 /* 8.2.13 Cause */
159 enum cbsp_cause {
160 CBSP_CAUSE_PARAM_NOT_RECOGNISED = 0x00,
161 CBSP_CAUSE_PARAM_VAL_INVALID = 0x01,
162 CBSP_CAUSE_MSG_REF_NOT_IDENTIFIED = 0x02,
163 CBSP_CAUSE_CELL_ID_NOT_VALID = 0x03,
164 CBSP_CAUSE_UNRECOGNISED_MSG = 0x04,
165 CBSP_CAUSE_MISSING_MAND_IE = 0x05,
166 CBSP_CAUSE_BSC_CAPACITY_EXCEEDED = 0x06,
167 CBSP_CAUSE_CELL_MEMORY_EXCEEDED = 0x07,
168 CBSP_CAUSE_BSC_MEMORY_EXCEEDED = 0x08,
169 CBSP_CAUSE_CB_NOT_SUPPORTED = 0x09,
170 CBSP_CAUSE_CB_NOT_OPERATIONAL = 0x0a,
171 CBSP_CAUSE_INCOMPATIBLE_DRX_PARAM = 0x0b,
172 CBSP_CAUSE_EXT_CHAN_NOT_SUPPORTED = 0x0c,
173 CBSP_CAUSE_MSG_REF_ALREADY_USED = 0x0d,
174 CBSP_CAUSE_UNSPECIFIED_ERROR = 0x0e,
175 CBSP_CAUSE_LAI_OR_LAC_NPT_VALID = 0x0f,
178 /* 8.2.15 */
179 static const value_string cbsp_recov_ind_vals[] = {
180 { 0x0, "CBS/emergency message data available" },
181 { 0x1, "CBS/emergency message data lost" },
182 { 0, NULL }
185 /* 8.2.17 */
186 static const value_string cbsp_emerg_ind_vals[] = {
187 { 0x0, "reserved" },
188 { 0x1, "ETWS information available" },
189 { 0, NULL }
192 /* 8.2.20 */
193 static const value_string cbsp_chan_ind_vals[] = {
194 { 0x0, "basic channel" },
195 { 0x1, "extended channel" },
196 { 0, NULL }
199 /* 8.2.24 */
200 static const value_string cbsp_bcast_msg_type_vals[] = {
201 { 0x0, "CBS message broadcasting" },
202 { 0x1, "emergency message broadcasting" },
203 { 0, NULL }
206 /* conversion function from 8.2.25 warning period to seconds */
207 static int cbsp_warn_period_to_secs(uint8_t warn_per)
209 if (warn_per <= 0x0a)
210 return warn_per;
211 else if (warn_per <= 0x14)
212 return 10 + (warn_per-0x0a)*2;
213 else if (warn_per <= 0x26)
214 return 30 + (warn_per-0x14)*5;
215 else if (warn_per <= 0x56)
216 return 120 + (warn_per-0x26)*10;
217 else if (warn_per <= 0xba)
218 return 600 + (warn_per-0x56)*60;
219 else
220 return -1;
223 static const value_string cbsp_cell_id_disc_vals[] = {
224 { CBSP_CIDD_WHOLE_CGI, "CGI" },
225 { CBSP_CIDD_LAC_CI, "LAC+CI" },
226 { CBSP_CIDD_CI, "CI" },
227 { CBSP_CIDD_LAI, "LAI" },
228 { CBSP_CIDD_LAC, "LAC" },
229 { CBSP_CIDD_ALL_IN_BSC, "BSS" },
230 { 0, NULL }
233 static const value_string cbsp_iei_names[] = {
234 { CBSP_IEI_MSG_CONTENT, "Message Content" },
235 { CBSP_IEI_OLD_SERIAL_NR, "Old Serial Number" },
236 { CBSP_IEI_NEW_SERIAL_NR, "New Serial Number" },
237 { CBSP_IEI_CELL_LIST, "Cell List" },
238 { CBSP_IEI_CATEGORY, "Category" },
239 { CBSP_IEI_REP_PERIOD, "Repetition Period" },
240 { CBSP_IEI_NUM_BCAST_REQ, "Number of Broadcasts Requested" },
241 { CBSP_IEI_NUM_BCAST_COMPL_LIST,"Number of Broadcasts Completed List" },
242 { CBSP_IEI_FAILURE_LIST, "Failure List" },
243 { CBSP_IEI_RR_LOADING_LIST, "Radio Resource Loading List" },
244 { CBSP_IEI_CAUSE, "Cause" },
245 { CBSP_IEI_DCS, "Data Coding Scheme" },
246 { CBSP_IEI_RECOVERY_IND, "Recovery Indication" },
247 { CBSP_IEI_MSG_ID, "Message Identifier" },
248 { CBSP_IEI_EMERG_IND, "Emergency Indicator" },
249 { CBSP_IEI_WARN_TYPE, "Warning Type" },
250 { CBSP_IEI_WARN_SEC_INFO, "Warning Security Information" },
251 { CBSP_IEI_CHANNEL_IND, "Channel Indicator" },
252 { CBSP_IEI_NUM_OF_PAGES, "Number of Pages" },
253 { CBSP_IEI_SCHEDULE_PERIOD, "Schedule Period" },
254 { CBSP_IEI_NUM_OF_RES_SLOTS, "Number of Reserved Slots" },
255 { CBSP_IEI_BCAST_MSG_TYPE, "Broadcast Message Type" },
256 { CBSP_IEI_WARNING_PERIOD, "Waring Period" },
257 { CBSP_IEI_KEEP_ALIVE_REP_PERIOD, "Keep Alive Repetition Period" },
258 { 0, NULL }
261 static const value_string cbsp_msg_type_names[] = {
262 { CBSP_MSGT_WRITE_REPLACE, "WRITE-REPLACE" },
263 { CBSP_MSGT_WRITE_REPLACE_COMPL, "WRITE-REPLACE COMPLETE" },
264 { CBSP_MSGT_WRITE_REPLACE_FAIL, "WRITE-REPLACE FAILURE" },
265 { CBSP_MSGT_KILL, "KILL" },
266 { CBSP_MSGT_KILL_COMPL, "KILL COMPLETE" },
267 { CBSP_MSGT_KILL_FAIL, "KILL FAILURE" },
268 { CBSP_MSGT_LOAD_QUERY, "LOAD QUERY" },
269 { CBSP_MSGT_LOAD_QUERY_COMPL, "LOAD QUERY COMPLETE" },
270 { CBSP_MSGT_LOAD_QUERY_FAIL, "LOAD QUERY FAILURE" },
271 { CBSP_MSGT_MSG_STATUS_QUERY, "MESSAGE STATUS QUERY" },
272 { CBSP_MSGT_MSG_STATUS_QUERY_COMPL, "MESSAGE STATUS QUERY COMPLETE" },
273 { CBSP_MSGT_MSG_STATUS_QUERY_FAIL, "MESSAGE STATUS QUERY FAILURE" },
274 { CBSP_MSGT_SET_DRX, "SET-DRX" },
275 { CBSP_MSGT_SET_DRX_COMPL, "SET-DRX COMPLETE" },
276 { CBSP_MSGT_SET_DRX_FAIL, "SET-DRX FAILURE" },
277 { CBSP_MSGT_RESET, "RESET" },
278 { CBSP_MSGT_RESET_COMPL, "RESET COMPLETE" },
279 { CBSP_MSGT_RESET_FAIL, "RESET FAILURE" },
280 { CBSP_MSGT_RESTART, "RESTART" },
281 { CBSP_MSGT_FAILURE, "FAILURE" },
282 { CBSP_MSGT_ERROR_IND, "ERROR INDICATION" },
283 { CBSP_MSGT_KEEP_ALIVE, "KEEP-ALIVE" },
284 { CBSP_MSGT_KEEP_ALIVE_COMPL, "KEEP-ALIVE COMPLETE" },
285 { 0, NULL }
288 static const value_string cbsp_category_names[] = {
289 { CBSP_CATEG_HIGH_PRIO, "High Priority" },
290 { CBSP_CATEG_BACKGROUND, "Background" },
291 { CBSP_CATEG_NORMAL, "Normal" },
292 { 0, NULL }
295 /* 8.2.13 */
296 static const value_string cbsp_cause_vals[] = {
297 { CBSP_CAUSE_PARAM_NOT_RECOGNISED, "Parameter-not-recognized" },
298 { CBSP_CAUSE_PARAM_VAL_INVALID, "Parameter-value-invalid" },
299 { CBSP_CAUSE_MSG_REF_NOT_IDENTIFIED, "Message-reference-not-identified" },
300 { CBSP_CAUSE_CELL_ID_NOT_VALID, "Cell-identity-not-valid" },
301 { CBSP_CAUSE_UNRECOGNISED_MSG, "Unrecognised-message" },
302 { CBSP_CAUSE_MISSING_MAND_IE, "Missing-mandatory-element" },
303 { CBSP_CAUSE_BSC_CAPACITY_EXCEEDED, "BSC-capacity-exceeded" },
304 { CBSP_CAUSE_CELL_MEMORY_EXCEEDED, "Cell-memory-exceeded" },
305 { CBSP_CAUSE_BSC_MEMORY_EXCEEDED, "BSC-memory-exceeded" },
306 { CBSP_CAUSE_CB_NOT_SUPPORTED, "Cell-broadcast-not-supported" },
307 { CBSP_CAUSE_CB_NOT_OPERATIONAL, "Cell-broadcast-not-operational" },
308 { CBSP_CAUSE_INCOMPATIBLE_DRX_PARAM, "Incompatible-DRX-parameter" },
309 { CBSP_CAUSE_EXT_CHAN_NOT_SUPPORTED, "Extended-channel-not-supported" },
310 { CBSP_CAUSE_MSG_REF_ALREADY_USED, "Message-reference-already-used" },
311 { CBSP_CAUSE_UNSPECIFIED_ERROR, "Unspecified-error" },
312 { CBSP_CAUSE_LAI_OR_LAC_NPT_VALID, "LAI-or-LAC-not-valid" },
313 { 0, NULL }
316 static const struct tlv_definition cbsp_att_tlvdef = {
317 .def = {
318 [CBSP_IEI_MSG_CONTENT] = { TLV_TYPE_FIXED, 83 },
319 [CBSP_IEI_OLD_SERIAL_NR] = { TLV_TYPE_FIXED, 2 },
320 [CBSP_IEI_NEW_SERIAL_NR] = { TLV_TYPE_FIXED, 2 },
321 [CBSP_IEI_CELL_LIST] = { TLV_TYPE_TL16V, 0 },
322 [CBSP_IEI_CATEGORY] = { TLV_TYPE_TV, 0 },
323 [CBSP_IEI_REP_PERIOD] = { TLV_TYPE_FIXED, 2 },
324 [CBSP_IEI_NUM_BCAST_REQ] = { TLV_TYPE_FIXED, 2 },
325 [CBSP_IEI_NUM_BCAST_COMPL_LIST] = { TLV_TYPE_TL16V, 0 },
326 [CBSP_IEI_FAILURE_LIST] = { TLV_TYPE_TL16V, 0 },
327 [CBSP_IEI_RR_LOADING_LIST] = { TLV_TYPE_TL16V, 0 },
328 [CBSP_IEI_CAUSE] = { TLV_TYPE_TV, 0 },
329 [CBSP_IEI_DCS] = { TLV_TYPE_TV, 0 },
330 [CBSP_IEI_RECOVERY_IND] = { TLV_TYPE_TV, 0 },
331 [CBSP_IEI_MSG_ID] = { TLV_TYPE_FIXED, 2 },
332 [CBSP_IEI_EMERG_IND] = { TLV_TYPE_TV, 0 },
333 [CBSP_IEI_WARN_TYPE] = { TLV_TYPE_FIXED, 2 },
334 [CBSP_IEI_WARN_SEC_INFO] = { TLV_TYPE_FIXED, 50 },
335 [CBSP_IEI_CHANNEL_IND] = { TLV_TYPE_TV, 0 },
336 [CBSP_IEI_NUM_OF_PAGES] = { TLV_TYPE_TV, 0 },
337 [CBSP_IEI_SCHEDULE_PERIOD] = { TLV_TYPE_TV, 0 },
338 [CBSP_IEI_NUM_OF_RES_SLOTS] = { TLV_TYPE_TV, 0 },
339 [CBSP_IEI_BCAST_MSG_TYPE] = { TLV_TYPE_TV, 0 },
340 [CBSP_IEI_WARNING_PERIOD] = { TLV_TYPE_TV, 0 },
341 [CBSP_IEI_KEEP_ALIVE_REP_PERIOD] = { TLV_TYPE_TV, 0 },
345 /***********************************************************************
346 * Wireshark Dissector Implementation
347 ***********************************************************************/
349 void proto_register_cbsp(void);
350 void proto_reg_handoff_cbsp(void);
352 static dissector_handle_t cbsp_handle;
354 static int proto_cbsp;
356 static int hf_cbsp_msg_type;
357 static int hf_cbsp_msg_len;
358 static int hf_cbsp_iei;
359 static int hf_cbsp_ie_len;
360 static int hf_cbsp_ie_payload;
362 static int hf_cbsp_old_serial_nr;
363 static int hf_cbsp_new_serial_nr;
364 static int hf_cbsp_category;
365 static int hf_cbsp_rep_period;
366 static int hf_cbsp_num_bcast_req;
367 static int hf_cbsp_cause;
368 static int hf_cbsp_dcs;
369 static int hf_cbsp_recovery_ind;
370 static int hf_cbsp_msg_id;
371 static int hf_cbsp_emerg_ind;
372 static int hf_cbsp_warn_type;
373 static int hf_cbsp_channel_ind;
374 static int hf_cbsp_num_of_pages;
375 static int hf_cbsp_cb_msg_page;
376 static int hf_cbsp_cbs_page_content;
377 static int hf_cbsp_sched_period;
378 static int hf_cbsp_num_of_res_slots;
379 static int hf_cbsp_bcast_msg_type;
380 static int hf_cbsp_warning_period;
381 static int hf_cbsp_keepalive_period;
382 static int hf_cbsp_user_info_length;
383 static int hf_cbsp_cell_id_disc;
384 static int hf_cbsp_cell_load1;
385 static int hf_cbsp_cell_load2;
386 static int hf_cbsp_num_bcast_compl;
387 static int hf_cbsp_num_bcast_info;
388 static int hf_cbsp_lac;
389 static int hf_cbsp_ci;
391 static int ett_cbsp;
392 static int ett_cbsp_ie;
393 static int ett_cbsp_cbs_data_coding;
394 static int ett_cbsp_cbs_page_content;
395 static int ett_cbsp_cell_list;
396 static int ett_cbsp_fail_list;
397 static int ett_cbsp_load_list;
398 static int ett_cbsp_num_bcast_compl_list;
400 static void
401 dissect_cbsp_content_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, int len, proto_tree *tree,
402 uint8_t sms_encoding, proto_item *ti)
404 proto_item *cbs_page_item;
405 tvbuff_t *next_tvb, *unpacked_tvb;
406 const uint8_t *pstr;
408 proto_tree_add_item(tree, hf_cbsp_user_info_length, tvb, offset, 1, ENC_NA);
409 cbs_page_item = proto_tree_add_item(tree, hf_cbsp_cb_msg_page, tvb, offset+1, len-1, ENC_NA);
410 next_tvb = tvb_new_subset_length(tvb, offset+1, len-1);
412 unpacked_tvb = dissect_cbs_data(sms_encoding, next_tvb, tree, pinfo, 0);
413 if (tree) {
414 unsigned captured_len = tvb_captured_length(unpacked_tvb);
415 proto_tree *cbs_page_subtree = proto_item_add_subtree(cbs_page_item, ett_cbsp_cbs_page_content);
416 proto_tree_add_item_ret_string(cbs_page_subtree, hf_cbsp_cbs_page_content, unpacked_tvb,
417 0, captured_len, ENC_UTF_8|ENC_NA, pinfo->pool,
418 &pstr);
419 proto_item_append_text(ti, ": '%s'", pstr);
423 /* Section 8.2.6 Cell List */
424 static int
425 dissect_cell_id_elem(uint8_t discr, tvbuff_t *tvb, packet_info *pinfo, unsigned offset, int len _U_,
426 proto_tree *tree, proto_item *ti)
428 unsigned base_offs = offset;
429 char *mcc_mnc;
430 uint32_t lac, ci;
432 switch (discr) {
433 case CBSP_CIDD_WHOLE_CGI:
434 mcc_mnc = dissect_e212_mcc_mnc_wmem_packet_str(tvb, pinfo, tree, offset, E212_NONE, true);
435 offset += 3;
436 proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_NA, &lac);
437 offset += 2;
438 proto_tree_add_item_ret_uint(tree, hf_cbsp_ci, tvb, offset, 2, ENC_NA, &ci);
439 offset += 2;
440 proto_item_append_text(ti, ": %s, LAC 0x%04x, CI 0x%04x", mcc_mnc, lac, ci);
441 break;
442 case CBSP_CIDD_LAC_CI:
443 proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_NA, &lac);
444 offset += 2;
445 proto_tree_add_item_ret_uint(tree, hf_cbsp_ci, tvb, offset, 2, ENC_NA, &ci);
446 offset += 2;
447 proto_item_append_text(ti, ": LAC 0%04x, CI 0x%04x", lac, ci);
448 break;
449 case CBSP_CIDD_CI:
450 proto_tree_add_item_ret_uint(tree, hf_cbsp_ci, tvb, offset, 2, ENC_NA, &ci);
451 offset += 2;
452 proto_item_append_text(ti, ": CI 0x%04x", ci);
453 break;
454 case CBSP_CIDD_LAI:
455 mcc_mnc = dissect_e212_mcc_mnc_wmem_packet_str(tvb, pinfo, tree, offset, E212_NONE, true);
456 offset += 3;
457 proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_NA, &lac);
458 offset += 2;
459 proto_item_append_text(ti, ": %s, LAC 0x%04x", mcc_mnc, lac);
460 break;
461 case CBSP_CIDD_LAC:
462 proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_NA, &lac);
463 offset += 2;
464 proto_item_append_text(ti, ": LAC 0x%04x", lac);
465 break;
466 case CBSP_CIDD_ALL_IN_BSC:
467 break;
468 default:
469 return -1;
472 return offset - base_offs;
475 /* return the length of a single list element of the given discriminator/type */
476 static int cell_id_len(uint8_t discr)
478 switch (discr) {
479 case CBSP_CIDD_WHOLE_CGI:
480 return 7;
481 case CBSP_CIDD_LAC_CI:
482 return 4;
483 case CBSP_CIDD_CI:
484 return 2;
485 case CBSP_CIDD_LAI:
486 return 5;
487 case CBSP_CIDD_LAC:
488 return 2;
489 case CBSP_CIDD_ALL_IN_BSC:
490 return 0;
491 default:
492 return -1;
496 static void
497 dissect_cell_id_list_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, unsigned len, proto_tree *tree,
498 proto_item *parent_ti)
500 unsigned base_offs = offset;
501 uint32_t discr;
502 unsigned count = 0;
504 /* list-global discriminator */
505 proto_tree_add_item_ret_uint(tree, hf_cbsp_cell_id_disc, tvb, offset, 1, ENC_NA, &discr);
506 discr &= 0x0f;
507 offset++;
509 /* iterate over list items */
510 while (offset - base_offs < len) {
511 proto_tree *elem_tree;
512 proto_item *ti;
513 int rc;
515 unsigned remain_len = len - (offset - base_offs);
516 elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr),
517 ett_cbsp_cell_list, &ti,
518 "Cell List Item");
519 rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti);
520 if (rc <= 0)
521 break;
522 offset += rc;
523 count++;
525 proto_item_append_text(parent_ti, " (%s): %u items",
526 val_to_str_const(discr, cbsp_cell_id_disc_vals, ""), count);
529 static void
530 dissect_rr_load_list_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, unsigned len, proto_tree *tree,
531 proto_item *parent_ti)
533 unsigned base_offs = offset;
534 uint32_t discr;
535 unsigned count = 0;
537 /* list-global discriminator */
538 proto_tree_add_item_ret_uint(tree, hf_cbsp_cell_id_disc, tvb, offset, 1, ENC_NA, &discr);
539 discr &= 0x0f;
540 offset++;
542 /* iterate over list items */
543 while (offset - base_offs < len) {
544 proto_tree *elem_tree;
545 uint32_t load1, load2;
546 proto_item *ti;
547 int rc;
549 unsigned remain_len = len - (offset - base_offs);
550 elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr)+2,
551 ett_cbsp_load_list, &ti,
552 "RR Load List Item");
553 rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti);
554 if (rc <= 0)
555 break;
556 offset += rc;
558 proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_cell_load1, tvb, offset++, 1,
559 ENC_NA, &load1);
560 proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_cell_load2, tvb, offset++, 1,
561 ENC_NA, &load2);
562 proto_item_append_text(ti, ": L1=%u%%, L2=%u%%", load1, load2);
563 count++;
565 proto_item_append_text(parent_ti, " (%s): %u items",
566 val_to_str_const(discr, cbsp_cell_id_disc_vals, ""), count);
569 static void
570 dissect_failure_list_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, unsigned len, proto_tree *tree,
571 proto_item *parent_ti)
573 unsigned base_offs = offset;
574 unsigned count = 0;
576 /* iterate over list items, each with its own discriminator */
577 while (offset - base_offs < len) {
578 proto_tree *elem_tree;
579 proto_item *ti;
580 unsigned remain_len, cause;
581 int rc;
583 uint8_t discr = tvb_get_uint8(tvb, offset) & 0x0f;
584 elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr)+2,
585 ett_cbsp_fail_list, &ti,
586 "Failure List Item");
587 proto_tree_add_item(elem_tree, hf_cbsp_cell_id_disc, tvb, offset++, 1, ENC_NA);
588 remain_len = len - (offset - base_offs);
589 rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti);
590 if (rc <= 0)
591 break;
592 offset += rc;
594 proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_cause, tvb, offset++, 1, ENC_NA, &cause);
595 proto_item_append_text(ti, ": Cause %s",
596 val_to_str_const(cause, cbsp_cause_vals, "Undefined"));
597 count++;
599 proto_item_append_text(parent_ti, ": %u items", count);
603 static void
604 dissect_bc_compl_list_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, unsigned len, proto_tree *tree,
605 proto_item *parent_ti)
607 unsigned base_offs = offset;
608 uint32_t discr;
609 unsigned count = 0;
611 /* list-global discriminator */
612 proto_tree_add_item_ret_uint(tree, hf_cbsp_cell_id_disc, tvb, offset, 1, ENC_NA, &discr);
613 discr &= 0x0f;
614 offset++;
616 /* iterate over list items */
617 while (offset - base_offs < len) {
618 proto_tree *elem_tree;
619 proto_item *ti;
620 uint32_t num_bc, num_bi;
621 int rc;
623 unsigned remain_len = len - (offset - base_offs);
624 elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr)+3,
625 ett_cbsp_num_bcast_compl_list, &ti,
626 "Number of Broadcasts completed");
627 rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti);
628 if (rc <= 0)
629 break;
630 offset += rc;
632 proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_num_bcast_compl, tvb, offset, 2, ENC_NA,
633 &num_bc);
634 offset += 2;
635 proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_num_bcast_info, tvb, offset++, 1, ENC_NA,
636 &num_bi);
637 proto_item_append_text(ti, ": NumBC=%u (%s)", num_bc,
638 val_to_str_const(num_bi, cbsp_num_bcast_shortinfo_vals, ""));
639 count++;
641 proto_item_append_text(parent_ti, " (%s): %u items",
642 val_to_str_const(discr, cbsp_cell_id_disc_vals, ""), count);
645 static int
646 dissect_cbsp_tlvs(tvbuff_t *tvb, int base_offs, int length, packet_info *pinfo, proto_tree *tree)
648 uint8_t sms_encoding = SMS_ENCODING_7BIT;
649 int offset = base_offs;
651 while (offset - base_offs < length) {
652 uint8_t tag; /* Information Element Identifier */
653 unsigned int len; /* Length of payload */
654 unsigned int len_len = 0;/* Length of "length" field (may be 0) */
655 proto_item *ti;
656 proto_tree *att_tree, *subtree;
657 uint32_t tmp_u;
658 int secs;
660 tag = tvb_get_uint8(tvb, offset);
661 offset++;
663 switch (cbsp_att_tlvdef.def[tag].type) {
664 case TLV_TYPE_TV:
665 len = 1;
666 len_len = 0;
667 break;
668 case TLV_TYPE_FIXED:
669 len = cbsp_att_tlvdef.def[tag].fixed_len;
670 len_len = 0;
671 break;
672 case TLV_TYPE_TLV:
673 len = tvb_get_uint8(tvb, offset);
674 break;
675 case TLV_TYPE_TL16V:
676 len = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
677 len_len = 2;
678 break;
679 default:
680 return length;
683 att_tree = proto_tree_add_subtree_format(tree, tvb, offset-1, 1+len_len+len,
684 ett_cbsp_ie, &ti, "IE: %s",
685 val_to_str(tag, cbsp_iei_names, "Unknown 0x%02x"));
686 proto_tree_add_item(att_tree, hf_cbsp_iei, tvb, offset-1, 1, ENC_NA);
687 if (len_len)
688 proto_tree_add_uint(att_tree, hf_cbsp_ie_len, tvb, offset, len_len, len);
690 offset += len_len;
692 switch (tag) {
693 case CBSP_IEI_MSG_CONTENT:
694 dissect_cbsp_content_ie(tvb, pinfo, offset, len, att_tree, sms_encoding, ti);
695 break;
696 case CBSP_IEI_OLD_SERIAL_NR:
697 proto_tree_add_item_ret_uint(att_tree, hf_cbsp_old_serial_nr, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u);
698 proto_item_append_text(ti, ": 0x%04x", tmp_u);
699 break;
700 case CBSP_IEI_NEW_SERIAL_NR:
701 proto_tree_add_item_ret_uint(att_tree, hf_cbsp_new_serial_nr, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u);
702 proto_item_append_text(ti, ": 0x%04x", tmp_u);
703 break;
704 case CBSP_IEI_CATEGORY:
705 proto_tree_add_item_ret_uint(att_tree, hf_cbsp_category, tvb, offset, len, ENC_NA,&tmp_u);
706 proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_category_names, ""));
707 break;
708 case CBSP_IEI_REP_PERIOD:
710 uint64_t tmp_u64;
711 crumb_spec_t cbsp_rep_period_crumbs[] = {
712 { 0, 8 },
713 { 12, 4 },
714 { 0, 0 }
717 proto_tree_add_split_bits_item_ret_val(att_tree, hf_cbsp_rep_period, tvb, offset<<3, cbsp_rep_period_crumbs, &tmp_u64);
718 proto_item_append_text(ti, ": %u", (uint16_t)tmp_u64);
720 break;
721 case CBSP_IEI_NUM_BCAST_REQ:
722 proto_tree_add_item_ret_uint(att_tree, hf_cbsp_num_bcast_req, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u);
723 proto_item_append_text(ti, ": %u", tmp_u);
724 break;
725 case CBSP_IEI_CAUSE:
726 proto_tree_add_item_ret_uint(att_tree, hf_cbsp_cause, tvb, offset, len, ENC_NA, &tmp_u);
727 proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_cause_vals, ""));
728 break;
729 case CBSP_IEI_DCS:
730 proto_tree_add_item_ret_uint(att_tree, hf_cbsp_dcs, tvb, offset, len, ENC_NA, &tmp_u);
731 subtree = proto_item_add_subtree(att_tree, ett_cbsp_cbs_data_coding);
732 sms_encoding = dissect_cbs_data_coding_scheme(tvb, pinfo, subtree, offset);
733 proto_item_append_text(ti, ": 0x%02x", tmp_u);
734 break;
735 case CBSP_IEI_RECOVERY_IND:
736 proto_tree_add_item(att_tree, hf_cbsp_recovery_ind, tvb, offset, len, ENC_NA);
737 break;
738 case CBSP_IEI_MSG_ID:
739 proto_tree_add_item_ret_uint(att_tree, hf_cbsp_msg_id, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u);
740 proto_item_append_text(ti, ": 0x%04x", tmp_u);
741 break;
742 case CBSP_IEI_EMERG_IND:
743 proto_tree_add_item_ret_uint(att_tree, hf_cbsp_emerg_ind, tvb, offset, len, ENC_NA, &tmp_u);
744 proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_emerg_ind_vals, ""));
745 break;
746 case CBSP_IEI_WARN_TYPE:
747 proto_tree_add_item(att_tree, hf_cbsp_warn_type, tvb, offset, len, ENC_NA);
748 break;
749 case CBSP_IEI_CHANNEL_IND:
750 proto_tree_add_item_ret_uint(att_tree, hf_cbsp_channel_ind, tvb, offset, len, ENC_NA, &tmp_u);
751 proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_chan_ind_vals, ""));
752 break;
753 case CBSP_IEI_NUM_OF_PAGES:
754 proto_tree_add_item_ret_uint(att_tree, hf_cbsp_num_of_pages, tvb, offset, len, ENC_NA, &tmp_u);
755 proto_item_append_text(ti, ": %u", tmp_u);
756 break;
757 case CBSP_IEI_SCHEDULE_PERIOD:
758 proto_tree_add_item(att_tree, hf_cbsp_sched_period, tvb, offset, len, ENC_NA);
759 break;
760 case CBSP_IEI_NUM_OF_RES_SLOTS:
761 proto_tree_add_item(att_tree, hf_cbsp_num_of_res_slots, tvb, offset, len, ENC_NA);
762 break;
763 case CBSP_IEI_BCAST_MSG_TYPE:
764 proto_tree_add_item_ret_uint(att_tree, hf_cbsp_bcast_msg_type, tvb, offset, len, ENC_NA, &tmp_u);
765 proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_bcast_msg_type_vals, ""));
766 break;
767 case CBSP_IEI_WARNING_PERIOD:
768 secs = cbsp_warn_period_to_secs(tvb_get_uint8(tvb, offset));
769 proto_tree_add_uint(att_tree, hf_cbsp_warning_period, tvb, offset, len, secs);
770 proto_item_append_text(ti, ": %u (s)", secs);
771 break;
772 case CBSP_IEI_KEEP_ALIVE_REP_PERIOD:
773 secs = cbsp_warn_period_to_secs(tvb_get_uint8(tvb, offset));
774 proto_tree_add_uint(att_tree, hf_cbsp_keepalive_period, tvb, offset, len, secs);
775 proto_item_append_text(ti, ": %u (s)", secs);
776 break;
777 case CBSP_IEI_CELL_LIST:
778 dissect_cell_id_list_ie(tvb, pinfo, offset, len, att_tree, ti);
779 break;
780 case CBSP_IEI_NUM_BCAST_COMPL_LIST:
781 dissect_bc_compl_list_ie(tvb, pinfo, offset, len, att_tree, ti);
782 break;
783 case CBSP_IEI_FAILURE_LIST:
784 dissect_failure_list_ie(tvb, pinfo, offset, len, att_tree, ti);
785 break;
786 case CBSP_IEI_RR_LOADING_LIST:
787 dissect_rr_load_list_ie(tvb, pinfo, offset, len, att_tree, ti);
788 break;
789 case CBSP_IEI_WARN_SEC_INFO:
790 /* this element is bogus / not used anyway, no need for a dissector */
791 default:
792 /* Unknown/unsupported IE: Print raw payload in addition to IEI + Length printed above */
793 proto_tree_add_item(att_tree, hf_cbsp_ie_payload, tvb, offset, len, ENC_NA);
794 break;
797 offset += len;
800 return offset;
803 /* This method dissects fully reassembled CBSP messages */
804 static int
805 dissect_cbsp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
807 int len_ind, offset = 0;
808 proto_item *ti;
809 proto_tree *cbsp_tree = NULL;
810 uint8_t msg_type;
811 const char *str;
814 //len = tvb_reported_length(tvb);
815 msg_type = tvb_get_uint8(tvb, offset + 0);
816 len_ind = tvb_get_uint24(tvb, offset + 1, ENC_BIG_ENDIAN);
818 col_set_str(pinfo->cinfo, COL_PROTOCOL, "CBSP");
820 col_clear(pinfo->cinfo, COL_INFO);
821 str = val_to_str(msg_type, cbsp_msg_type_names, "Unknown CBSP Message Type 0x%02x");
822 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", str);
824 if (tree) {
825 ti = proto_tree_add_protocol_format(tree, proto_cbsp, tvb, 0,
826 len_ind + FRAME_HEADER_LEN, "CBSP %s", str);
827 cbsp_tree = proto_item_add_subtree(ti, ett_cbsp);
829 proto_tree_add_item(cbsp_tree, hf_cbsp_msg_type,
830 tvb, offset, 1, ENC_BIG_ENDIAN);
831 offset++;
833 proto_tree_add_item(cbsp_tree, hf_cbsp_msg_len, tvb, offset, 3, ENC_BIG_ENDIAN);
834 offset += 3;
836 dissect_cbsp_tlvs(tvb, offset, tvb_reported_length_remaining(tvb, offset), pinfo,
837 cbsp_tree);
840 return tvb_captured_length(tvb);
843 /* determine PDU length of protocol cbsp */
844 static unsigned
845 get_cbsp_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
847 uint32_t len_ind = tvb_get_uint24(tvb, offset + 1, ENC_BIG_ENDIAN);
849 return len_ind + FRAME_HEADER_LEN;
852 /* The main dissecting routine */
853 static int
854 dissect_cbsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
856 tcp_dissect_pdus(tvb, pinfo, tree, true, FRAME_HEADER_LEN,
857 get_cbsp_message_len, dissect_cbsp_message, data);
858 return tvb_captured_length(tvb);
861 void
862 proto_register_cbsp(void)
864 static hf_register_info hf[] = {
865 { &hf_cbsp_msg_type, { "Message Type", "cbsp.msg_type",
866 FT_UINT8, BASE_DEC, VALS(cbsp_msg_type_names), 0, NULL, HFILL } },
867 { &hf_cbsp_msg_len, { "Message Length", "cbsp.msg_len",
868 FT_UINT24, BASE_DEC, NULL, 0, NULL, HFILL } },
870 { &hf_cbsp_iei, { "Information Element Identifier", "cbsp.ie.iei",
871 FT_UINT8, BASE_DEC, VALS(cbsp_iei_names), 0, NULL, HFILL } },
872 { &hf_cbsp_ie_len, { "Information Element Length", "cbsp.ie.len",
873 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
874 { &hf_cbsp_ie_payload, { "Information Element Payload", "cbsp.ie.payload",
875 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
877 { &hf_cbsp_old_serial_nr, { "Old Serial Number", "cbsp.old_serial_nr",
878 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
879 { &hf_cbsp_new_serial_nr, { "New Serial Number", "cbsp.new_serial_nr",
880 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
881 { &hf_cbsp_category, { "Category", "cbsp.category",
882 FT_UINT8, BASE_HEX, VALS(cbsp_category_names), 0, NULL, HFILL } },
883 { &hf_cbsp_rep_period, { "Repetition Period (units of 1.883s)", "cbsp.rep_period",
884 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
885 { &hf_cbsp_num_bcast_req, { "Number of Broadcasts Requested", "cbsp.num_bcast_req",
886 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
887 { &hf_cbsp_cause, { "Cause", "cbsp.cause",
888 FT_UINT8, BASE_HEX, VALS(cbsp_cause_vals), 0, NULL, HFILL } },
889 { &hf_cbsp_dcs, { "Data Coding Scheme", "cbsp.dcs",
890 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
891 { &hf_cbsp_recovery_ind, { "Recovery Indication", "cbsp.recovery_ind",
892 FT_UINT8, BASE_HEX, VALS(cbsp_recov_ind_vals), 0, NULL, HFILL } },
893 { &hf_cbsp_msg_id, { "Message Identifier", "cbsp.message_id",
894 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
895 { &hf_cbsp_emerg_ind, { "Emergency Indicator", "cbsp.emergency_ind",
896 FT_UINT8, BASE_HEX, VALS(cbsp_emerg_ind_vals), 0, NULL, HFILL } },
897 { &hf_cbsp_warn_type, { "Warning Type", "cbsp.warn_type",
898 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
899 { &hf_cbsp_channel_ind, { "Channel Indicator", "cbsp.channel_ind",
900 FT_UINT8, BASE_HEX, VALS(cbsp_chan_ind_vals), 0, NULL, HFILL } },
901 { &hf_cbsp_num_of_pages, { "Number of Pages", "cbsp.num_of_pages",
902 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
903 { &hf_cbsp_cb_msg_page, { "CBS Message Information Page", "cbsp.cb_msg_page",
904 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
905 { &hf_cbsp_cbs_page_content, { "CBS Page Content", "cbsp.cb_page_content",
906 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
907 { &hf_cbsp_sched_period, { "Schedule Period", "cbsp.sched_period",
908 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
909 { &hf_cbsp_num_of_res_slots, { "Number of Reserved Slots", "cbsp.num_of_res_slots",
910 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
911 { &hf_cbsp_bcast_msg_type, { "Broadcast Message Type", "cbsp.bcast_msg_type",
912 FT_UINT8, BASE_DEC, VALS(cbsp_bcast_msg_type_vals), 0, NULL, HFILL } },
913 { &hf_cbsp_warning_period, { "Warning Period", "cbsp.warning_period",
914 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
915 { &hf_cbsp_keepalive_period, { "Keepalive Repetition Period", "cbsp.keepalive_rep_period",
916 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
917 { &hf_cbsp_user_info_length, { "User Information Length", "cbsp.user_info_len",
918 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
919 { &hf_cbsp_cell_id_disc, { "Cell ID Discriminator", "cbsp.cell_id_disc",
920 FT_UINT8, BASE_DEC, VALS(cbsp_cell_id_disc_vals), 0, NULL, HFILL } },
921 { &hf_cbsp_cell_load1, { "Radio Resource Load 1", "cbsp.rr_load1",
922 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
923 { &hf_cbsp_cell_load2, { "Radio Resource Load 2", "cbsp.rr_load2",
924 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
925 { &hf_cbsp_num_bcast_compl, { "Number of Broadcasts Completed", "cbsp.num_bcast_compl",
926 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
927 { &hf_cbsp_num_bcast_info, { "Number of Broadcasts Info", "cbsp.num_bcast_info",
928 FT_UINT8, BASE_HEX, VALS(cbsp_num_bcast_info_vals), 0, NULL, HFILL } },
929 { &hf_cbsp_lac, { "Location Area Code (LAC)", "cbsp.lac",
930 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
931 { &hf_cbsp_ci, { "Cell Identifier (CI)", "cbsp.ci",
932 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
934 static int *ett[] = {
935 &ett_cbsp,
936 &ett_cbsp_ie,
937 &ett_cbsp_cbs_data_coding,
938 &ett_cbsp_cbs_page_content,
939 &ett_cbsp_cell_list,
940 &ett_cbsp_fail_list,
941 &ett_cbsp_load_list,
942 &ett_cbsp_num_bcast_compl_list,
945 proto_cbsp = proto_register_protocol("3GPP/GSM Cell Broadcast Service Protocol", "cbsp", "cbsp");
946 cbsp_handle = register_dissector("cbsp", dissect_cbsp, proto_cbsp);
947 proto_register_field_array(proto_cbsp, hf, array_length(hf));
948 proto_register_subtree_array(ett, array_length(ett));
951 void
952 proto_reg_handoff_cbsp(void)
954 dissector_add_uint_with_preference("tcp.port", CBSP_TCP_PORT, cbsp_handle);
958 * Editor modelines - https://www.wireshark.org/tools/modelines.html
960 * Local variables:
961 * c-basic-offset: 8
962 * tab-width: 8
963 * indent-tabs-mode: t
964 * End:
966 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
967 * :indentSize=8:tabSize=8:noTabs=false: