Coverage Report

Created: 2025-12-27 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-gsm_cbsp.c
Line
Count
Source
1
/* packet-gsm_cbsp.c
2
 * Dissector for GSM / 3GPP TS 48.049 Cell Broadcast Service Protocol (CBSP)
3
 *
4
 * (C) 2018-2019 by Harald Welte <laforge@gnumonks.org>
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 *
12
 */
13
14
#include "config.h"
15
16
#include <epan/packet.h>
17
#include <epan/conversation.h>
18
#include <epan/asn1.h>
19
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()
25
26
1.09k
#define FRAME_HEADER_LEN 4
27
28
/***********************************************************************
29
 * TLV related definitions
30
 ***********************************************************************/
31
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 */
36
};
37
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 */
45
};
46
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 */
51
};
52
53
/*! Definition of All 256 IE / TLV */
54
struct tlv_definition {
55
  struct tlv_def def[256];
56
};
57
58
59
/***********************************************************************
60
 * CBSP Protocol Definitions, see libosmocore/include/gsm/protocol/gsm_48_049.h
61
 ***********************************************************************/
62
63
14
#define CBSP_TCP_PORT 48049
64
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,
91
};
92
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,
118
};
119
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,
125
};
126
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,
132
};
133
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 }
139
};
140
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 }
146
};
147
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,
156
};
157
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,
176
};
177
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 }
183
};
184
185
/* 8.2.17 */
186
static const value_string cbsp_emerg_ind_vals[] = {
187
  { 0x0,  "reserved" },
188
  { 0x1,  "ETWS information available" },
189
  { 0, NULL }
190
};
191
192
/* 8.2.20 */
193
static const value_string cbsp_chan_ind_vals[] = {
194
  { 0x0,  "basic channel" },
195
  { 0x1,  "extended channel" },
196
  { 0, NULL }
197
};
198
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 }
204
};
205
206
/* conversion function from 8.2.25 warning period to seconds */
207
static int cbsp_warn_period_to_secs(uint8_t warn_per)
208
30
{
209
30
  if (warn_per <= 0x0a)
210
2
    return warn_per;
211
28
  else if (warn_per <= 0x14)
212
2
    return 10 + (warn_per-0x0a)*2;
213
26
  else if (warn_per <= 0x26)
214
16
    return 30 + (warn_per-0x14)*5;
215
10
  else if (warn_per <= 0x56)
216
1
    return 120 + (warn_per-0x26)*10;
217
9
  else if (warn_per <= 0xba)
218
6
    return 600 + (warn_per-0x56)*60;
219
3
  else
220
3
    return -1;
221
30
}
222
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 }
231
};
232
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 }
259
};
260
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 }
286
};
287
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 }
293
};
294
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 }
314
};
315
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 },
342
  },
343
};
344
345
/***********************************************************************
346
 * Wireshark Dissector Implementation
347
 ***********************************************************************/
348
349
void proto_register_cbsp(void);
350
void proto_reg_handoff_cbsp(void);
351
352
static dissector_handle_t cbsp_handle;
353
354
static int proto_cbsp;
355
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;
361
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;
390
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;
399
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)
403
10
{
404
10
  proto_item *cbs_page_item;
405
10
  tvbuff_t *next_tvb, *unpacked_tvb;
406
10
  const uint8_t *pstr;
407
408
10
  proto_tree_add_item(tree, hf_cbsp_user_info_length, tvb, offset, 1, ENC_NA);
409
10
  cbs_page_item = proto_tree_add_item(tree, hf_cbsp_cb_msg_page, tvb, offset+1, len-1, ENC_NA);
410
10
  next_tvb = tvb_new_subset_length(tvb, offset+1, len-1);
411
412
10
  unpacked_tvb = dissect_cbs_data(sms_encoding, next_tvb, tree, pinfo, 0);
413
10
  if (tree) {
414
8
    unsigned captured_len = tvb_captured_length(unpacked_tvb);
415
8
    proto_tree *cbs_page_subtree = proto_item_add_subtree(cbs_page_item, ett_cbsp_cbs_page_content);
416
8
    proto_tree_add_item_ret_string(cbs_page_subtree, hf_cbsp_cbs_page_content, unpacked_tvb,
417
8
            0, captured_len, ENC_UTF_8|ENC_NA, pinfo->pool,
418
8
            &pstr);
419
8
    proto_item_append_text(ti, ": '%s'", pstr);
420
8
  }
421
10
}
422
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)
427
1.30k
{
428
1.30k
  unsigned base_offs = offset;
429
1.30k
  char *mcc_mnc;
430
1.30k
  uint32_t lac, ci;
431
432
1.30k
  switch (discr) {
433
113
  case CBSP_CIDD_WHOLE_CGI:
434
113
    mcc_mnc = dissect_e212_mcc_mnc_wmem_packet_str(tvb, pinfo, tree, offset, E212_NONE, true);
435
113
    offset += 3;
436
113
    proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_BIG_ENDIAN, &lac);
437
113
    offset += 2;
438
113
    proto_tree_add_item_ret_uint(tree, hf_cbsp_ci, tvb, offset, 2, ENC_BIG_ENDIAN, &ci);
439
113
    offset += 2;
440
113
    proto_item_append_text(ti, ": %s, LAC 0x%04x, CI 0x%04x", mcc_mnc, lac, ci);
441
113
    break;
442
56
  case CBSP_CIDD_LAC_CI:
443
56
    proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_BIG_ENDIAN, &lac);
444
56
    offset += 2;
445
56
    proto_tree_add_item_ret_uint(tree, hf_cbsp_ci, tvb, offset, 2, ENC_BIG_ENDIAN, &ci);
446
56
    offset += 2;
447
56
    proto_item_append_text(ti, ": LAC 0%04x, CI 0x%04x", lac, ci);
448
56
    break;
449
743
  case CBSP_CIDD_CI:
450
743
    proto_tree_add_item_ret_uint(tree, hf_cbsp_ci, tvb, offset, 2, ENC_BIG_ENDIAN, &ci);
451
743
    offset += 2;
452
743
    proto_item_append_text(ti, ": CI 0x%04x", ci);
453
743
    break;
454
109
  case CBSP_CIDD_LAI:
455
109
    mcc_mnc = dissect_e212_mcc_mnc_wmem_packet_str(tvb, pinfo, tree, offset, E212_NONE, true);
456
109
    offset += 3;
457
109
    proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_BIG_ENDIAN, &lac);
458
109
    offset += 2;
459
109
    proto_item_append_text(ti, ": %s, LAC 0x%04x", mcc_mnc, lac);
460
109
    break;
461
259
  case CBSP_CIDD_LAC:
462
259
    proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_BIG_ENDIAN, &lac);
463
259
    offset += 2;
464
259
    proto_item_append_text(ti, ": LAC 0x%04x", lac);
465
259
    break;
466
4
  case CBSP_CIDD_ALL_IN_BSC:
467
4
    break;
468
17
  default:
469
17
    return -1;
470
1.30k
  }
471
472
1.26k
  return offset - base_offs;
473
1.30k
}
474
475
/* return the length of a single list element of the given discriminator/type */
476
static int cell_id_len(uint8_t discr)
477
1.30k
{
478
1.30k
  switch (discr) {
479
113
  case CBSP_CIDD_WHOLE_CGI:
480
113
    return 7;
481
56
  case CBSP_CIDD_LAC_CI:
482
56
    return 4;
483
743
  case CBSP_CIDD_CI:
484
743
    return 2;
485
109
  case CBSP_CIDD_LAI:
486
109
    return 5;
487
259
  case CBSP_CIDD_LAC:
488
259
    return 2;
489
4
  case CBSP_CIDD_ALL_IN_BSC:
490
4
    return 0;
491
17
  default:
492
17
    return -1;
493
1.30k
  }
494
1.30k
}
495
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)
499
22
{
500
22
  unsigned base_offs = offset;
501
22
  uint32_t discr;
502
22
  unsigned count = 0;
503
504
  /* list-global discriminator */
505
22
  proto_tree_add_item_ret_uint(tree, hf_cbsp_cell_id_disc, tvb, offset, 1, ENC_NA, &discr);
506
22
  discr &= 0x0f;
507
22
  offset++;
508
509
  /* iterate over list items */
510
1.12k
  while (offset - base_offs < len) {
511
1.10k
    proto_tree *elem_tree;
512
1.10k
    proto_item *ti;
513
1.10k
    int rc;
514
515
1.10k
    unsigned remain_len = len - (offset - base_offs);
516
1.10k
    elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr),
517
1.10k
               ett_cbsp_cell_list, &ti,
518
1.10k
               "Cell List Item");
519
1.10k
    rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti);
520
1.10k
    if (rc <= 0)
521
2
      break;
522
1.10k
    offset += rc;
523
1.10k
    count++;
524
1.10k
  }
525
22
  proto_item_append_text(parent_ti, " (%s): %u items",
526
22
        val_to_str_const(discr, cbsp_cell_id_disc_vals, ""), count);
527
22
}
528
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)
532
14
{
533
14
  unsigned base_offs = offset;
534
14
  uint32_t discr;
535
14
  unsigned count = 0;
536
537
  /* list-global discriminator */
538
14
  proto_tree_add_item_ret_uint(tree, hf_cbsp_cell_id_disc, tvb, offset, 1, ENC_NA, &discr);
539
14
  discr &= 0x0f;
540
14
  offset++;
541
542
  /* iterate over list items */
543
115
  while (offset - base_offs < len) {
544
108
    proto_tree *elem_tree;
545
108
    uint32_t load1, load2;
546
108
    proto_item *ti;
547
108
    int rc;
548
549
108
    unsigned remain_len = len - (offset - base_offs);
550
108
    elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr)+2,
551
108
               ett_cbsp_load_list, &ti,
552
108
               "RR Load List Item");
553
108
    rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti);
554
108
    if (rc <= 0)
555
7
      break;
556
101
    offset += rc;
557
558
101
    proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_cell_load1, tvb, offset++, 1,
559
101
               ENC_NA, &load1);
560
101
    proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_cell_load2, tvb, offset++, 1,
561
101
               ENC_NA, &load2);
562
101
    proto_item_append_text(ti, ": L1=%u%%, L2=%u%%", load1, load2);
563
101
    count++;
564
101
  }
565
14
  proto_item_append_text(parent_ti, " (%s): %u items",
566
14
        val_to_str_const(discr, cbsp_cell_id_disc_vals, ""), count);
567
14
}
568
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)
572
9
{
573
9
  unsigned base_offs = offset;
574
9
  unsigned count = 0;
575
576
  /* iterate over list items, each with its own discriminator */
577
48
  while (offset - base_offs < len) {
578
47
    proto_tree *elem_tree;
579
47
    proto_item *ti;
580
47
    unsigned remain_len, cause;
581
47
    int rc;
582
583
47
    uint8_t discr = tvb_get_uint8(tvb, offset) & 0x0f;
584
47
    elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr)+2,
585
47
               ett_cbsp_fail_list, &ti,
586
47
               "Failure List Item");
587
47
    proto_tree_add_item(elem_tree, hf_cbsp_cell_id_disc, tvb, offset++, 1, ENC_NA);
588
47
    remain_len = len - (offset - base_offs);
589
47
    rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti);
590
47
    if (rc <= 0)
591
8
      break;
592
39
    offset += rc;
593
594
39
    proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_cause, tvb, offset++, 1, ENC_NA, &cause);
595
39
    proto_item_append_text(ti, ": Cause %s",
596
39
          val_to_str_const(cause, cbsp_cause_vals, "Undefined"));
597
39
    count++;
598
39
  }
599
9
  proto_item_append_text(parent_ti, ": %u items", count);
600
601
9
}
602
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)
606
8
{
607
8
  unsigned base_offs = offset;
608
8
  uint32_t discr;
609
8
  unsigned count = 0;
610
611
  /* list-global discriminator */
612
8
  proto_tree_add_item_ret_uint(tree, hf_cbsp_cell_id_disc, tvb, offset, 1, ENC_NA, &discr);
613
8
  discr &= 0x0f;
614
8
  offset++;
615
616
  /* iterate over list items */
617
46
  while (offset - base_offs < len) {
618
42
    proto_tree *elem_tree;
619
42
    proto_item *ti;
620
42
    uint32_t num_bc, num_bi;
621
42
    int rc;
622
623
42
    unsigned remain_len = len - (offset - base_offs);
624
42
    elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr)+3,
625
42
               ett_cbsp_num_bcast_compl_list, &ti,
626
42
               "Number of Broadcasts completed");
627
42
    rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti);
628
42
    if (rc <= 0)
629
4
      break;
630
38
    offset += rc;
631
632
38
    proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_num_bcast_compl, tvb, offset, 2, ENC_BIG_ENDIAN,
633
38
               &num_bc);
634
38
    offset += 2;
635
38
    proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_num_bcast_info, tvb, offset++, 1, ENC_NA,
636
38
               &num_bi);
637
38
    proto_item_append_text(ti, ": NumBC=%u (%s)", num_bc,
638
38
          val_to_str_const(num_bi, cbsp_num_bcast_shortinfo_vals, ""));
639
38
    count++;
640
38
  }
641
8
  proto_item_append_text(parent_ti, " (%s): %u items",
642
8
        val_to_str_const(discr, cbsp_cell_id_disc_vals, ""), count);
643
8
}
644
645
static int
646
dissect_cbsp_tlvs(tvbuff_t *tvb, int base_offs, int length, packet_info *pinfo, proto_tree *tree)
647
490
{
648
490
  uint8_t sms_encoding = SMS_ENCODING_7BIT;
649
490
  int offset = base_offs;
650
651
1.14k
  while (offset - base_offs < length) {
652
817
    uint8_t tag;     /* Information Element Identifier */
653
817
    unsigned int len;  /* Length of payload */
654
817
    unsigned int len_len = 0;/* Length of "length" field (may be 0) */
655
817
    proto_item *ti;
656
817
    proto_tree *att_tree, *subtree;
657
817
    uint32_t tmp_u;
658
817
    int secs;
659
660
817
    tag = tvb_get_uint8(tvb, offset);
661
817
    offset++;
662
663
817
    switch (cbsp_att_tlvdef.def[tag].type) {
664
415
    case TLV_TYPE_TV:
665
415
      len = 1;
666
415
      len_len = 0;
667
415
      break;
668
222
    case TLV_TYPE_FIXED:
669
222
      len = cbsp_att_tlvdef.def[tag].fixed_len;
670
222
      len_len = 0;
671
222
      break;
672
0
    case TLV_TYPE_TLV:
673
0
      len = tvb_get_uint8(tvb, offset);
674
0
      break;
675
53
    case TLV_TYPE_TL16V:
676
53
      len = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
677
53
      len_len = 2;
678
53
      break;
679
118
    default:
680
118
      return length;
681
817
    }
682
683
690
    att_tree = proto_tree_add_subtree_format(tree, tvb, offset-1, 1+len_len+len,
684
690
            ett_cbsp_ie, &ti, "IE: %s",
685
690
            val_to_str(pinfo->pool, tag, cbsp_iei_names, "Unknown 0x%02x"));
686
690
    proto_tree_add_item(att_tree, hf_cbsp_iei, tvb, offset-1, 1, ENC_NA);
687
690
    if (len_len)
688
53
      proto_tree_add_uint(att_tree, hf_cbsp_ie_len, tvb, offset, len_len, len);
689
690
690
    offset += len_len;
691
692
690
    switch (tag) {
693
10
    case CBSP_IEI_MSG_CONTENT:
694
10
      dissect_cbsp_content_ie(tvb, pinfo, offset, len, att_tree, sms_encoding, ti);
695
10
      break;
696
27
    case CBSP_IEI_OLD_SERIAL_NR:
697
27
      proto_tree_add_item_ret_uint(att_tree, hf_cbsp_old_serial_nr, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u);
698
27
      proto_item_append_text(ti, ": 0x%04x", tmp_u);
699
27
      break;
700
5
    case CBSP_IEI_NEW_SERIAL_NR:
701
5
      proto_tree_add_item_ret_uint(att_tree, hf_cbsp_new_serial_nr, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u);
702
5
      proto_item_append_text(ti, ": 0x%04x", tmp_u);
703
5
      break;
704
73
    case CBSP_IEI_CATEGORY:
705
73
      proto_tree_add_item_ret_uint(att_tree, hf_cbsp_category, tvb, offset, len, ENC_NA,&tmp_u);
706
73
      proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_category_names, ""));
707
73
      break;
708
10
    case CBSP_IEI_REP_PERIOD:
709
10
      {
710
10
        uint64_t tmp_u64;
711
10
        crumb_spec_t cbsp_rep_period_crumbs[] = {
712
10
          {  0, 8 },
713
10
          { 12, 4 },
714
10
          {  0, 0 }
715
10
        };
716
717
10
        proto_tree_add_split_bits_item_ret_val(att_tree, hf_cbsp_rep_period, tvb, offset<<3, cbsp_rep_period_crumbs, &tmp_u64);
718
10
        proto_item_append_text(ti, ": %u", (uint16_t)tmp_u64);
719
10
      }
720
10
      break;
721
44
    case CBSP_IEI_NUM_BCAST_REQ:
722
44
      proto_tree_add_item_ret_uint(att_tree, hf_cbsp_num_bcast_req, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u);
723
44
      proto_item_append_text(ti, ": %u", tmp_u);
724
44
      break;
725
4
    case CBSP_IEI_CAUSE:
726
4
      proto_tree_add_item_ret_uint(att_tree, hf_cbsp_cause, tvb, offset, len, ENC_NA, &tmp_u);
727
4
      proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_cause_vals, ""));
728
4
      break;
729
41
    case CBSP_IEI_DCS:
730
41
      proto_tree_add_item_ret_uint(att_tree, hf_cbsp_dcs, tvb, offset, len, ENC_NA, &tmp_u);
731
41
      subtree = proto_item_add_subtree(att_tree, ett_cbsp_cbs_data_coding);
732
41
      sms_encoding = dissect_cbs_data_coding_scheme(tvb, pinfo, subtree, offset);
733
41
      proto_item_append_text(ti, ": 0x%02x", tmp_u);
734
41
      break;
735
4
    case CBSP_IEI_RECOVERY_IND:
736
4
      proto_tree_add_item(att_tree, hf_cbsp_recovery_ind, tvb, offset, len, ENC_NA);
737
4
      break;
738
76
    case CBSP_IEI_MSG_ID:
739
76
      proto_tree_add_item_ret_uint(att_tree, hf_cbsp_msg_id, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u);
740
76
      proto_item_append_text(ti, ": 0x%04x", tmp_u);
741
76
      break;
742
101
    case CBSP_IEI_EMERG_IND:
743
101
      proto_tree_add_item_ret_uint(att_tree, hf_cbsp_emerg_ind, tvb, offset, len, ENC_NA, &tmp_u);
744
101
      proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_emerg_ind_vals, ""));
745
101
      break;
746
46
    case CBSP_IEI_WARN_TYPE:
747
46
      proto_tree_add_item(att_tree, hf_cbsp_warn_type, tvb, offset, len, ENC_NA);
748
46
      break;
749
53
    case CBSP_IEI_CHANNEL_IND:
750
53
      proto_tree_add_item_ret_uint(att_tree, hf_cbsp_channel_ind, tvb, offset, len, ENC_NA, &tmp_u);
751
53
      proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_chan_ind_vals, ""));
752
53
      break;
753
22
    case CBSP_IEI_NUM_OF_PAGES:
754
22
      proto_tree_add_item_ret_uint(att_tree, hf_cbsp_num_of_pages, tvb, offset, len, ENC_NA, &tmp_u);
755
22
      proto_item_append_text(ti, ": %u", tmp_u);
756
22
      break;
757
48
    case CBSP_IEI_SCHEDULE_PERIOD:
758
48
      proto_tree_add_item(att_tree, hf_cbsp_sched_period, tvb, offset, len, ENC_NA);
759
48
      break;
760
33
    case CBSP_IEI_NUM_OF_RES_SLOTS:
761
33
      proto_tree_add_item(att_tree, hf_cbsp_num_of_res_slots, tvb, offset, len, ENC_NA);
762
33
      break;
763
6
    case CBSP_IEI_BCAST_MSG_TYPE:
764
6
      proto_tree_add_item_ret_uint(att_tree, hf_cbsp_bcast_msg_type, tvb, offset, len, ENC_NA, &tmp_u);
765
6
      proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_bcast_msg_type_vals, ""));
766
6
      break;
767
29
    case CBSP_IEI_WARNING_PERIOD:
768
29
      secs = cbsp_warn_period_to_secs(tvb_get_uint8(tvb, offset));
769
29
      proto_tree_add_uint(att_tree, hf_cbsp_warning_period, tvb, offset, len, secs);
770
29
      proto_item_append_text(ti, ": %u (s)", secs);
771
29
      break;
772
1
    case CBSP_IEI_KEEP_ALIVE_REP_PERIOD:
773
1
      secs = cbsp_warn_period_to_secs(tvb_get_uint8(tvb, offset));
774
1
      proto_tree_add_uint(att_tree, hf_cbsp_keepalive_period, tvb, offset, len, secs);
775
1
      proto_item_append_text(ti, ": %u (s)", secs);
776
1
      break;
777
22
    case CBSP_IEI_CELL_LIST:
778
22
      dissect_cell_id_list_ie(tvb, pinfo, offset, len, att_tree, ti);
779
22
      break;
780
8
    case CBSP_IEI_NUM_BCAST_COMPL_LIST:
781
8
      dissect_bc_compl_list_ie(tvb, pinfo, offset, len, att_tree, ti);
782
8
      break;
783
9
    case CBSP_IEI_FAILURE_LIST:
784
9
      dissect_failure_list_ie(tvb, pinfo, offset, len, att_tree, ti);
785
9
      break;
786
14
    case CBSP_IEI_RR_LOADING_LIST:
787
14
      dissect_rr_load_list_ie(tvb, pinfo, offset, len, att_tree, ti);
788
14
      break;
789
4
    case CBSP_IEI_WARN_SEC_INFO:
790
      /* this element is bogus / not used anyway, no need for a dissector */
791
4
    default:
792
      /* Unknown/unsupported IE: Print raw payload in addition to IEI + Length printed above */
793
4
      proto_tree_add_item(att_tree, hf_cbsp_ie_payload, tvb, offset, len, ENC_NA);
794
4
      break;
795
690
    }
796
797
658
    offset += len;
798
658
  }
799
800
331
  return offset;
801
490
}
802
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_)
806
490
{
807
490
  int len_ind, offset = 0;
808
490
  proto_item *ti;
809
490
  proto_tree *cbsp_tree = NULL;
810
490
  uint8_t msg_type;
811
490
  const char *str;
812
813
814
  //len = tvb_reported_length(tvb);
815
490
  msg_type = tvb_get_uint8(tvb, offset + 0);
816
490
  len_ind = tvb_get_uint24(tvb, offset + 1, ENC_BIG_ENDIAN);
817
818
490
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "CBSP");
819
820
490
  col_clear(pinfo->cinfo, COL_INFO);
821
490
  str = val_to_str(pinfo->pool, msg_type, cbsp_msg_type_names, "Unknown CBSP Message Type 0x%02x");
822
490
  col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", str);
823
824
490
  if (tree) {
825
490
    ti = proto_tree_add_protocol_format(tree, proto_cbsp, tvb, 0,
826
490
                len_ind + FRAME_HEADER_LEN, "CBSP %s", str);
827
490
    cbsp_tree = proto_item_add_subtree(ti, ett_cbsp);
828
829
490
    proto_tree_add_item(cbsp_tree, hf_cbsp_msg_type,
830
490
            tvb, offset, 1, ENC_BIG_ENDIAN);
831
490
    offset++;
832
833
490
    proto_tree_add_item(cbsp_tree, hf_cbsp_msg_len, tvb, offset, 3, ENC_BIG_ENDIAN);
834
490
    offset += 3;
835
836
490
    dissect_cbsp_tlvs(tvb, offset, tvb_reported_length_remaining(tvb, offset), pinfo,
837
490
          cbsp_tree);
838
490
  }
839
840
490
  return tvb_captured_length(tvb);
841
490
}
842
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_)
846
490
{
847
490
  uint32_t len_ind =  tvb_get_uint24(tvb, offset + 1, ENC_BIG_ENDIAN);
848
849
490
  return len_ind + FRAME_HEADER_LEN;
850
490
}
851
852
/* The main dissecting routine */
853
static int
854
dissect_cbsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
855
110
{
856
110
  tcp_dissect_pdus(tvb, pinfo, tree, true, FRAME_HEADER_LEN,
857
110
       get_cbsp_message_len, dissect_cbsp_message, data);
858
110
  return tvb_captured_length(tvb);
859
110
}
860
861
void
862
proto_register_cbsp(void)
863
14
{
864
14
  static hf_register_info hf[] = {
865
14
    { &hf_cbsp_msg_type, { "Message Type", "cbsp.msg_type",
866
14
      FT_UINT8, BASE_DEC, VALS(cbsp_msg_type_names), 0, NULL, HFILL } },
867
14
    { &hf_cbsp_msg_len, { "Message Length", "cbsp.msg_len",
868
14
      FT_UINT24, BASE_DEC, NULL, 0, NULL, HFILL } },
869
870
14
    { &hf_cbsp_iei, { "Information Element Identifier", "cbsp.ie.iei",
871
14
      FT_UINT8, BASE_DEC, VALS(cbsp_iei_names), 0, NULL, HFILL } },
872
14
    { &hf_cbsp_ie_len, { "Information Element Length", "cbsp.ie.len",
873
14
      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
874
14
    { &hf_cbsp_ie_payload, { "Information Element Payload", "cbsp.ie.payload",
875
14
      FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
876
877
14
    { &hf_cbsp_old_serial_nr, { "Old Serial Number", "cbsp.old_serial_nr",
878
14
      FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
879
14
    { &hf_cbsp_new_serial_nr, { "New Serial Number", "cbsp.new_serial_nr",
880
14
      FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
881
14
    { &hf_cbsp_category, { "Category", "cbsp.category",
882
14
      FT_UINT8, BASE_HEX, VALS(cbsp_category_names), 0, NULL, HFILL } },
883
14
    { &hf_cbsp_rep_period, { "Repetition Period (units of 1.883s)", "cbsp.rep_period",
884
14
      FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
885
14
    { &hf_cbsp_num_bcast_req, { "Number of Broadcasts Requested", "cbsp.num_bcast_req",
886
14
      FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
887
14
    { &hf_cbsp_cause, { "Cause", "cbsp.cause",
888
14
      FT_UINT8, BASE_HEX, VALS(cbsp_cause_vals), 0, NULL, HFILL } },
889
14
    { &hf_cbsp_dcs, { "Data Coding Scheme", "cbsp.dcs",
890
14
      FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
891
14
    { &hf_cbsp_recovery_ind, { "Recovery Indication", "cbsp.recovery_ind",
892
14
      FT_UINT8, BASE_HEX, VALS(cbsp_recov_ind_vals), 0, NULL, HFILL } },
893
14
    { &hf_cbsp_msg_id, { "Message Identifier", "cbsp.message_id",
894
14
      FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
895
14
    { &hf_cbsp_emerg_ind, { "Emergency Indicator", "cbsp.emergency_ind",
896
14
      FT_UINT8, BASE_HEX, VALS(cbsp_emerg_ind_vals), 0, NULL, HFILL } },
897
14
    { &hf_cbsp_warn_type, { "Warning Type", "cbsp.warn_type",
898
14
      FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
899
14
    { &hf_cbsp_channel_ind, { "Channel Indicator", "cbsp.channel_ind",
900
14
      FT_UINT8, BASE_HEX, VALS(cbsp_chan_ind_vals), 0, NULL, HFILL } },
901
14
    { &hf_cbsp_num_of_pages, { "Number of Pages", "cbsp.num_of_pages",
902
14
      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
903
14
    { &hf_cbsp_cb_msg_page, { "CBS Message Information Page", "cbsp.cb_msg_page",
904
14
      FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
905
14
    { &hf_cbsp_cbs_page_content, { "CBS Page Content", "cbsp.cb_page_content",
906
14
      FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
907
14
    { &hf_cbsp_sched_period, { "Schedule Period", "cbsp.sched_period",
908
14
      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
909
14
    { &hf_cbsp_num_of_res_slots, { "Number of Reserved Slots", "cbsp.num_of_res_slots",
910
14
      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
911
14
    { &hf_cbsp_bcast_msg_type, { "Broadcast Message Type", "cbsp.bcast_msg_type",
912
14
      FT_UINT8, BASE_DEC, VALS(cbsp_bcast_msg_type_vals), 0, NULL, HFILL } },
913
14
    { &hf_cbsp_warning_period, { "Warning Period", "cbsp.warning_period",
914
14
      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
915
14
    { &hf_cbsp_keepalive_period, { "Keepalive Repetition Period", "cbsp.keepalive_rep_period",
916
14
      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
917
14
    { &hf_cbsp_user_info_length, { "User Information Length", "cbsp.user_info_len",
918
14
      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
919
14
    { &hf_cbsp_cell_id_disc, { "Cell ID Discriminator", "cbsp.cell_id_disc",
920
14
      FT_UINT8, BASE_DEC, VALS(cbsp_cell_id_disc_vals), 0, NULL, HFILL } },
921
14
    { &hf_cbsp_cell_load1, { "Radio Resource Load 1", "cbsp.rr_load1",
922
14
      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
923
14
    { &hf_cbsp_cell_load2, { "Radio Resource Load 2", "cbsp.rr_load2",
924
14
      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
925
14
    { &hf_cbsp_num_bcast_compl, { "Number of Broadcasts Completed", "cbsp.num_bcast_compl",
926
14
      FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
927
14
    { &hf_cbsp_num_bcast_info, { "Number of Broadcasts Info", "cbsp.num_bcast_info",
928
14
      FT_UINT8, BASE_HEX, VALS(cbsp_num_bcast_info_vals), 0, NULL, HFILL } },
929
14
    { &hf_cbsp_lac, { "Location Area Code (LAC)", "cbsp.lac",
930
14
      FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
931
14
    { &hf_cbsp_ci, { "Cell Identifier (CI)", "cbsp.ci",
932
14
      FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
933
14
  };
934
14
  static int *ett[] = {
935
14
    &ett_cbsp,
936
14
    &ett_cbsp_ie,
937
14
    &ett_cbsp_cbs_data_coding,
938
14
    &ett_cbsp_cbs_page_content,
939
14
    &ett_cbsp_cell_list,
940
14
    &ett_cbsp_fail_list,
941
14
    &ett_cbsp_load_list,
942
14
    &ett_cbsp_num_bcast_compl_list,
943
14
  };
944
945
14
  proto_cbsp = proto_register_protocol("3GPP/GSM Cell Broadcast Service Protocol", "cbsp", "cbsp");
946
14
  cbsp_handle = register_dissector("cbsp", dissect_cbsp, proto_cbsp);
947
14
  proto_register_field_array(proto_cbsp, hf, array_length(hf));
948
14
  proto_register_subtree_array(ett, array_length(ett));
949
14
}
950
951
void
952
proto_reg_handoff_cbsp(void)
953
14
{
954
14
  dissector_add_uint_with_preference("tcp.port", CBSP_TCP_PORT, cbsp_handle);
955
14
}
956
957
/*
958
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
959
 *
960
 * Local variables:
961
 * c-basic-offset: 8
962
 * tab-width: 8
963
 * indent-tabs-mode: t
964
 * End:
965
 *
966
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
967
 * :indentSize=8:tabSize=8:noTabs=false:
968
 */