Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-gsm_abis_pgsl.c
blobd0e91fb385ea8ff36c40fc38204e3e5a224e6148
1 /* packet-gsm_abis_pgsl.c
2 * Routines for packet dissection of Ericsson GSM A-bis P-GSL
3 * Copyright 2010-2016 by Harald Welte <laforge@gnumonks.org>
5 * P-GSL is an Ericsson-specific packetized version of replacing PCU-CCU
6 * TRAU frames on 8k/16k E1 sub-slots with a paketized frame format
7 * which can be transported over LAPD on a SuperChannel (E1 timeslot
8 * bundle) or L2TP.
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * SPDX-License-Identifier: GPL-2.0-or-later
17 #include "config.h"
19 #include <epan/packet.h>
20 #include <epan/tfs.h>
21 #include <epan/prefs.h>
23 #include "packet-gsm_rlcmac.h"
24 #include "packet-gsm_a_common.h"
26 void proto_register_abis_pgsl(void);
27 void proto_reg_handoff_abis_pgsl(void);
29 enum {
30 SUB_RLCMAC_UL,
31 SUB_RLCMAC_DL,
33 SUB_MAX
36 static dissector_handle_t pgsl_handle;
37 static dissector_handle_t sub_handles[SUB_MAX];
39 /* initialize the protocol and registered fields */
40 static int proto_abis_pgsl;
42 /* P-GSL header */
43 static int hf_pgsl_version;
44 static int hf_pgsl_msg_disc;
45 static int hf_pgsl_tn_bitmap;
46 static int hf_pgsl_trx_seqno;
47 static int hf_pgsl_afnd;
48 static int hf_pgsl_afnu;
49 static int hf_pgsl_ccu_ta;
50 static int hf_pgsl_ack_req;
51 static int hf_pgsl_tn_resource;
52 static int hf_pgsl_tn_seqno;
53 static int hf_pgsl_data_len;
54 static int hf_pgsl_cause;
55 static int hf_pgsl_addl_info;
56 static int hf_pgsl_ack_ind;
57 static int hf_pgsl_data_ind;
58 static int hf_pgsl_ucm;
59 static int hf_pgsl_cs;
60 static int hf_pgsl_timing_offset;
61 static int hf_pgsl_power_control;
62 static int hf_pgsl_ir_tfi;
63 static int hf_pgsl_ir_sign_type;
64 static int hf_pgsl_codec_delay;
65 static int hf_pgsl_codec_cs;
66 static int hf_pgsl_codec_rxlev;
67 static int hf_pgsl_codec_parity;
68 static int hf_pgsl_codec_bqm;
69 static int hf_pgsl_codec_mean_bep;
70 static int hf_pgsl_codec_cv_bep;
71 static int hf_pgsl_codec_q;
72 static int hf_pgsl_codec_q1;
73 static int hf_pgsl_codec_q2;
74 static int hf_pgsl_pacch;
75 static int hf_pgsl_ab_rxlev;
76 static int hf_pgsl_ab_acc_delay;
77 static int hf_pgsl_ab_abi;
78 static int hf_pgsl_ab_ab_type;
80 /* initialize the subtree pointers */
81 static int ett_pgsl;
82 static int ett_pacch;
84 static bool abis_pgsl_ir;
86 #define PGSL_MSG_DLDATA_REQ 1
87 #define PGSL_MSG_DLDATA_IND 2
88 #define PGSL_MSG_ULDATA_IND 3
89 #define PGSL_MSG_STATUS_IND 4
91 static const value_string pgsl_msg_disc_vals[] = {
92 { PGSL_MSG_DLDATA_REQ, "PGSL-DLDATA-REQ" },
93 { PGSL_MSG_DLDATA_IND, "PGSL-DLDATA-IND" },
94 { PGSL_MSG_ULDATA_IND, "PGSL-ULDATA-IND" },
95 { PGSL_MSG_STATUS_IND, "PGSL-STATUS-IND" },
96 { 0, NULL }
99 static const true_false_string pgsl_q_vals = {
100 "Bad",
101 "Good"
104 static const value_string pgsl_msg_cause_vals[] = {
105 { 0, "Frame discarded in CCU, too late" },
106 { 1, "Frame discarded in CCU, too late or OOM" },
107 { 2, "Frame(s) missing in sequence detected by CCU" },
108 { 3, "Frame Format Error" },
109 { 0, NULL }
112 static const value_string pgsl_cs_vals[] = {
113 { 0, "AB" },
114 { 1, "CS-1" },
115 { 2, "CS-2" },
116 { 3, "CS-3" },
117 { 4, "CS-4" },
118 { 5, "Header Type 1" },
119 { 6, "Header Type 2" },
120 { 7, "Header Type 3" },
121 { 0, NULL }
124 static const value_string pgsl_ucm_vals[] = {
125 { 1, "Normal Burst (GSMK CS1/CS2/CS3/CS4)" },
126 { 2, "Normal Burst (CS1 or MCS1 to MCS9)" },
127 { 3, "Access Burst (8 bit, Training Sequence 0)" },
128 { 4, "Access Burst (8 bit or 11 bit, Training Sequence 0/1/2)" },
129 { 0, NULL }
132 static const value_string pgsl_ir_sign_type_vals[] = {
133 { 0, "IR Update Indication" },
134 { 1, "IR Start Indication" },
135 { 2, "IR Stop Indication" },
136 { 3, "No IR Information" },
137 { 0, NULL }
140 static const value_string pgsl_ab_type_vals[] = {
141 { 0, "8-bit RACH" },
142 { 1, "11-bit RACH (TS0)" },
143 { 2, "11-bit RACH (TS1)" },
144 { 3, "11-bit RACH (TS2)" },
145 { 0, NULL }
148 static const value_string pgsl_ab_abi_vals[] = {
149 { 0, "Not Valid" },
150 { 7, "Valid" },
151 { 0, NULL }
154 static RLCMAC_block_format_t pgsl_cs_to_rlcmac_cs(uint8_t pgsl_cs)
156 static const RLCMAC_block_format_t tbl[8] = {
157 RLCMAC_PRACH,
158 RLCMAC_CS1,
159 RLCMAC_CS2,
160 RLCMAC_CS3,
161 RLCMAC_CS4,
162 RLCMAC_HDR_TYPE_1,
163 RLCMAC_HDR_TYPE_2,
164 RLCMAC_HDR_TYPE_3,
167 if (pgsl_cs >= 8)
168 return RLCMAC_CS1;
169 else
170 return tbl[pgsl_cs];
173 /* length of an EGPRS RLC data block for given MCS */
174 static const unsigned data_block_len_by_mcs[] = {
175 0, /* MCS0 */
176 22, /* MCS1 */
184 74, /* MCS9 */
185 0, /* MCS_INVALID */
188 /* determine the number of rlc data blocks and their size / offsets */
189 static void
190 setup_rlc_mac_priv(RlcMacPrivateData_t *rm, bool is_uplink,
191 unsigned *n_calls, unsigned *data_block_bits, unsigned *data_block_offsets)
193 unsigned nc, dbl = 0, dbo[2] = {0,0};
195 DISSECTOR_ASSERT(rm->mcs < G_N_ELEMENTS(data_block_len_by_mcs));
196 dbl = data_block_len_by_mcs[rm->mcs];
198 switch (rm->block_format) {
199 case RLCMAC_HDR_TYPE_1:
200 nc = 3;
201 dbo[0] = is_uplink ? 5*8 + 6 : 5*8 + 0;
202 dbo[1] = dbo[0] + dbl * 8 + 2;
203 break;
204 case RLCMAC_HDR_TYPE_2:
205 nc = 2;
206 dbo[0] = is_uplink ? 4*8 + 5 : 3*8 + 4;
207 break;
208 case RLCMAC_HDR_TYPE_3:
209 nc = 2;
210 dbo[0] = 3*8 + 7;
211 break;
212 default:
213 nc = 1;
214 break;
217 *n_calls = nc;
218 *data_block_bits = dbl * 8 + 2;
219 data_block_offsets[0] = dbo[0];
220 data_block_offsets[1] = dbo[1];
223 /* bit-shift the entire 'src' of length 'length_bytes' by 'offset_bits'
224 * and store the reuslt to caller-allocated 'buffer'. The shifting is
225 * done lsb-first, unlike tvb_new_octet_aligned() */
226 static void clone_aligned_buffer_lsbf(unsigned offset_bits, unsigned length_bytes,
227 const uint8_t *src, uint8_t *buffer)
229 unsigned hdr_bytes;
230 unsigned extra_bits;
231 unsigned i;
233 uint8_t c, last_c;
234 uint8_t *dst;
236 hdr_bytes = offset_bits / 8;
237 extra_bits = offset_bits % 8;
239 if (extra_bits == 0) {
240 /* It is aligned already */
241 memmove(buffer, src + hdr_bytes, length_bytes);
242 return;
245 dst = buffer;
246 src = src + hdr_bytes;
247 last_c = *(src++);
249 for (i = 0; i < length_bytes; i++) {
250 c = src[i];
251 *(dst++) = (last_c >> extra_bits) | (c << (8 - extra_bits));
252 last_c = c;
256 /* obtain an (aligned) EGPRS data block with given bit-offset and
257 * bit-length from the parent TVB */
258 static tvbuff_t *get_egprs_data_block(tvbuff_t *tvb, unsigned offset_bits,
259 unsigned length_bits, packet_info *pinfo)
261 tvbuff_t *aligned_tvb;
262 const unsigned initial_spare_bits = 6;
263 uint8_t *aligned_buf;
264 unsigned min_src_length_bytes = (offset_bits + length_bits + 7) / 8;
265 unsigned length_bytes = (initial_spare_bits + length_bits + 7) / 8;
267 tvb_ensure_bytes_exist(tvb, 0, min_src_length_bytes);
269 aligned_buf = (uint8_t *) wmem_alloc(pinfo->pool, length_bytes);
271 /* Copy the data out of the tvb to an aligned buffer */
272 clone_aligned_buffer_lsbf(
273 offset_bits - initial_spare_bits, length_bytes,
274 tvb_get_ptr(tvb, 0, min_src_length_bytes),
275 aligned_buf);
277 /* clear spare bits and move block header bits to the right */
278 aligned_buf[0] = aligned_buf[0] >> initial_spare_bits;
280 aligned_tvb = tvb_new_child_real_data(tvb, aligned_buf,
281 length_bytes, length_bytes);
282 add_new_data_source(pinfo, aligned_tvb, "Aligned EGPRS data bits");
284 return aligned_tvb;
287 /* Dissect a P-GSL ACess Burst Message */
288 static void
289 dissect_pgsl_access_burst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
290 RlcMacPrivateData_t *rlcmac_data)
292 proto_item *ti;
293 proto_tree *pacch_tree;
294 tvbuff_t *data_tvb;
295 unsigned rxlev, abtype, abi;
296 uint16_t acc_delay;
298 ti = proto_tree_add_item(tree, hf_pgsl_pacch, tvb, offset, 5, ENC_NA);
299 pacch_tree = proto_item_add_subtree(ti, ett_pacch);
301 proto_tree_add_item_ret_uint(pacch_tree, hf_pgsl_ab_rxlev, tvb, offset++, 1, ENC_NA, &rxlev);
302 /* Access Delay is encoded as 10-bit field with the lowest 8
303 * bits in the first octet, with the two highest bits in the
304 * lowest bits of the second octet */
305 acc_delay = tvb_get_uint8(tvb, offset);
306 acc_delay |= tvb_get_bits8(tvb, (offset+1)*8+6, 2) << 8;
307 proto_tree_add_uint(pacch_tree, hf_pgsl_ab_acc_delay, tvb, offset, 2, acc_delay);
308 /* ABI and AB Type are in the same octet as the acc_dely msb's */
309 offset++;
310 proto_tree_add_item_ret_uint(pacch_tree, hf_pgsl_ab_abi, tvb, offset, 1, ENC_NA, &abi);
311 proto_tree_add_item_ret_uint(pacch_tree, hf_pgsl_ab_ab_type, tvb, offset, 1, ENC_NA, &abtype);
312 offset++;
313 /* Update the 'master' item */
314 if (abi) {
315 proto_item_append_text(ti, " Valid, RxLev %u, Delay %u bits, Type %s", rxlev, acc_delay,
316 val_to_str(abtype, pgsl_ab_type_vals, "0x%x"));
317 /* decode actual access burst */
318 data_tvb = tvb_new_subset_length(tvb, offset, 2);
319 call_dissector_with_data(sub_handles[SUB_RLCMAC_UL], data_tvb, pinfo, pacch_tree,
320 (void *) rlcmac_data);
321 } else
322 proto_item_append_text(ti, " Invalid, RxLev %u", rxlev);
325 /* Dissect a given (E)GPRS RLC/MAC block */
326 static void
327 dissect_gprs_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, bool uplink,
328 RlcMacPrivateData_t *rlcmac_data)
330 dissector_handle_t rlcmac_dissector;
331 tvbuff_t *data_tvb;
332 unsigned data_block_bits, data_block_offsets[2];
333 unsigned num_calls;
335 if (uplink)
336 rlcmac_dissector = sub_handles[SUB_RLCMAC_UL];
337 else
338 rlcmac_dissector = sub_handles[SUB_RLCMAC_DL];
340 /* we need to call the dissector several times
341 * incase of EGPRS, once for each header, and
342 * once for the paylod */
343 switch (rlcmac_data->block_format) {
344 case RLCMAC_PRACH:
345 /* contains information for four access bursts */
346 dissect_pgsl_access_burst(tvb, 0, pinfo, tree, rlcmac_data);
347 dissect_pgsl_access_burst(tvb, 5, pinfo, tree, rlcmac_data);
348 dissect_pgsl_access_burst(tvb, 10, pinfo, tree, rlcmac_data);
349 dissect_pgsl_access_burst(tvb, 15, pinfo, tree, rlcmac_data);
350 break;
351 case RLCMAC_HDR_TYPE_1:
352 case RLCMAC_HDR_TYPE_2:
353 case RLCMAC_HDR_TYPE_3:
354 /* First call of RLC/MAC dissector for header */
355 call_dissector_with_data(rlcmac_dissector, tvb,
356 pinfo, tree, (void *) rlcmac_data);
358 /* now determine how to proceed for data */
359 setup_rlc_mac_priv(rlcmac_data, uplink,
360 &num_calls, &data_block_bits, data_block_offsets);
361 /* and call dissector one or two time for the data blocks */
362 if (num_calls >= 2) {
363 rlcmac_data->flags = GSM_RLC_MAC_EGPRS_BLOCK1;
364 data_tvb = get_egprs_data_block(tvb, data_block_offsets[0],
365 data_block_bits, pinfo);
366 call_dissector_with_data(rlcmac_dissector, data_tvb, pinfo, tree,
367 (void *) rlcmac_data);
369 if (num_calls == 3) {
370 rlcmac_data->flags = GSM_RLC_MAC_EGPRS_BLOCK2;
371 data_tvb = get_egprs_data_block(tvb, data_block_offsets[1],
372 data_block_bits, pinfo);
373 call_dissector_with_data(rlcmac_dissector, data_tvb, pinfo, tree,
374 (void *) rlcmac_data);
376 break;
377 default:
378 /* regular GPRS CS doesn't need any
379 * shifting/re-alignment or even separate calls for
380 * header and data blocks. We simply call the dissector
381 * as-is */
382 call_dissector_with_data(rlcmac_dissector, tvb, pinfo, tree,
383 (void *) rlcmac_data);
387 static int
388 dissect_abis_pgsl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
390 proto_item *ti;
391 proto_tree *pgsl_tree;
392 int offset = 0;
393 tvbuff_t *next_tvb;
394 uint32_t msg_disc, len, ack_data_ind, cs, fn;
395 RlcMacPrivateData_t rlcmac_data = {0};
397 col_set_str(pinfo->cinfo, COL_PROTOCOL, "P-GSL");
399 ti = proto_tree_add_item(tree, proto_abis_pgsl, tvb, 0, -1, ENC_NA);
400 pgsl_tree = proto_item_add_subtree(ti, ett_pgsl);
402 proto_tree_add_item(pgsl_tree, hf_pgsl_version, tvb, offset, 1, ENC_NA);
403 proto_tree_add_item_ret_uint(pgsl_tree, hf_pgsl_msg_disc, tvb, offset, 1, ENC_NA, &msg_disc);
404 offset++;
406 col_append_str(pinfo->cinfo, COL_INFO, val_to_str(msg_disc, pgsl_msg_disc_vals, "Unknown (%u)"));
408 rlcmac_data.magic = GSM_RLC_MAC_MAGIC_NUMBER;
410 switch (msg_disc) {
411 case PGSL_MSG_DLDATA_REQ:
412 proto_tree_add_item(pgsl_tree, hf_pgsl_tn_bitmap, tvb, offset++, 1, ENC_NA);
413 proto_tree_add_item(pgsl_tree, hf_pgsl_trx_seqno, tvb, offset++, 1, ENC_NA);
414 proto_tree_add_item(pgsl_tree, hf_pgsl_afnd, tvb, offset, 3, ENC_LITTLE_ENDIAN);
415 offset += 3;
416 proto_tree_add_item(pgsl_tree, hf_pgsl_ccu_ta, tvb, offset++, 1, ENC_NA);
417 proto_tree_add_item(pgsl_tree, hf_pgsl_ack_req, tvb, offset++, 1, ENC_NA);
418 break;
419 case PGSL_MSG_DLDATA_IND:
420 proto_tree_add_item(pgsl_tree, hf_pgsl_tn_resource, tvb, offset++, 1, ENC_NA);
421 proto_tree_add_item(pgsl_tree, hf_pgsl_tn_seqno, tvb, offset++, 1, ENC_NA);
422 proto_tree_add_item_ret_uint(pgsl_tree, hf_pgsl_afnd, tvb, offset, 3, ENC_LITTLE_ENDIAN, &fn);
423 rlcmac_data.frame_number = fn;
424 offset += 3;
425 ack_data_ind = tvb_get_uint8(tvb, offset);
426 proto_tree_add_item(pgsl_tree, hf_pgsl_ack_ind, tvb, offset, 1, ENC_NA);
427 proto_tree_add_item(pgsl_tree, hf_pgsl_data_ind, tvb, offset++, 1, ENC_NA);
428 if (ack_data_ind & 1) {
429 /* Codec Control */
430 proto_tree_add_item(pgsl_tree, hf_pgsl_ucm, tvb, offset, 1, ENC_NA);
431 proto_tree_add_item_ret_uint(pgsl_tree, hf_pgsl_cs, tvb, offset, 1, ENC_NA, &cs);
432 proto_tree_add_item(pgsl_tree, hf_pgsl_timing_offset, tvb, offset+1, 1, ENC_NA);
433 offset += 2;
434 /* Power Control */
435 proto_tree_add_item(pgsl_tree, hf_pgsl_power_control, tvb, offset++, 1, ENC_NA);
436 if (abis_pgsl_ir) {
437 /* Incremental Redundancy */
438 proto_tree_add_item(pgsl_tree, hf_pgsl_ir_tfi, tvb, offset, 1, ENC_NA);
439 proto_tree_add_item(pgsl_tree, hf_pgsl_ir_sign_type, tvb, offset, 1, ENC_NA);
440 proto_tree_add_item(pgsl_tree, hf_pgsl_tn_bitmap, tvb, offset+1, 1, ENC_NA);
441 offset += 2;
443 /* Data length */
444 proto_tree_add_item_ret_uint(pgsl_tree, hf_pgsl_data_len, tvb, offset++, 1, ENC_NA, &len);
445 rlcmac_data.block_format = pgsl_cs_to_rlcmac_cs(cs);
446 /* Generate tvb containing only the RLC/MAC data */
447 next_tvb = tvb_new_subset_length(tvb, offset, len);
448 dissect_gprs_data(next_tvb, pinfo, tree, 0, &rlcmac_data);
450 break;
451 case PGSL_MSG_ULDATA_IND:
452 proto_tree_add_item(pgsl_tree, hf_pgsl_tn_resource, tvb, offset++, 1, ENC_NA);
453 proto_tree_add_item(pgsl_tree, hf_pgsl_tn_seqno, tvb, offset++, 1, ENC_NA);
454 proto_tree_add_item_ret_uint(pgsl_tree, hf_pgsl_afnu, tvb, offset, 3, ENC_LITTLE_ENDIAN, &fn);
455 rlcmac_data.frame_number = fn;
456 offset += 3;
457 /* Codec Status */
458 proto_tree_add_item(pgsl_tree, hf_pgsl_codec_delay, tvb, offset, 1, ENC_NA);
459 proto_tree_add_item_ret_uint(pgsl_tree, hf_pgsl_codec_cs, tvb, offset, 1, ENC_NA, &cs);
460 proto_tree_add_item(pgsl_tree, hf_pgsl_codec_rxlev, tvb, offset+1, 1, ENC_NA);
461 if (cs <= 4) {
462 /* GPRS */
463 proto_tree_add_item(pgsl_tree, hf_pgsl_codec_parity, tvb, offset+2, 1, ENC_NA);
464 proto_tree_add_item(pgsl_tree, hf_pgsl_codec_bqm, tvb, offset+2, 1, ENC_NA);
465 } else {
466 /* EGPRS */
467 proto_tree_add_item(pgsl_tree, hf_pgsl_codec_mean_bep, tvb, offset+2, 1, ENC_NA);
468 proto_tree_add_item(pgsl_tree, hf_pgsl_codec_cv_bep, tvb, offset+3, 1, ENC_NA);
469 proto_tree_add_item(pgsl_tree, hf_pgsl_codec_q, tvb, offset+3, 1, ENC_NA);
470 proto_tree_add_item(pgsl_tree, hf_pgsl_codec_q1, tvb, offset+3, 1, ENC_NA);
471 proto_tree_add_item(pgsl_tree, hf_pgsl_codec_q2, tvb, offset+3, 1, ENC_NA);
473 offset += 4;
474 /* Data Length */
475 proto_tree_add_item_ret_uint(pgsl_tree, hf_pgsl_data_len, tvb, offset++, 1, ENC_NA, &len);
476 rlcmac_data.block_format = pgsl_cs_to_rlcmac_cs(cs);
477 /* Generate tvb containing only the RLC/MAC data */
478 next_tvb = tvb_new_subset_length(tvb, offset, len);
479 dissect_gprs_data(next_tvb, pinfo, tree, 1, &rlcmac_data);
480 break;
481 case PGSL_MSG_STATUS_IND:
482 proto_tree_add_item(pgsl_tree, hf_pgsl_tn_resource, tvb, offset++, 1, ENC_NA);
483 proto_tree_add_item(pgsl_tree, hf_pgsl_tn_seqno, tvb, offset++, 1, ENC_NA);
484 proto_tree_add_item(pgsl_tree, hf_pgsl_afnu, tvb, offset, 3, ENC_NA);
485 offset += 3;
486 proto_tree_add_item(pgsl_tree, hf_pgsl_cause, tvb, offset++, 1, ENC_NA);
487 proto_tree_add_item(pgsl_tree, hf_pgsl_addl_info, tvb, offset++, 1, ENC_NA);
488 break;
491 return offset;
494 void
495 proto_register_abis_pgsl(void)
497 static hf_register_info hf[] = {
498 { &hf_pgsl_version,
499 { "Version", "gsm_abis_pgsl.version",
500 FT_UINT8, BASE_DEC, NULL, 0xf0,
501 NULL, HFILL }
503 { &hf_pgsl_msg_disc,
504 { "Message Discriminator", "gsm_abis_pgsl.msg_disc",
505 FT_UINT8, BASE_DEC, VALS(pgsl_msg_disc_vals), 0x0f,
506 NULL, HFILL }
508 { &hf_pgsl_tn_bitmap,
509 { "TN Bitmap", "gsm_abis_pgsl.tn_bitmap",
510 FT_UINT8, BASE_HEX, NULL, 0,
511 NULL, HFILL }
513 { &hf_pgsl_trx_seqno,
514 { "TRX Sequence Number", "gsm_abis_pgsl.trx_seqno",
515 FT_UINT8, BASE_DEC, NULL, 0,
516 "Per-TRX Sequence Number", HFILL }
518 { &hf_pgsl_afnd,
519 { "aFNd", "gsm_abis_pgsl.a_fn_d",
520 FT_UINT24, BASE_DEC, NULL, 0,
521 "Frame Number (Downlink)", HFILL }
523 { &hf_pgsl_afnu,
524 { "aFNu", "gsm_abis_pgsl.a_fn_u",
525 FT_UINT24, BASE_DEC, NULL, 0,
526 "Frame Number (Uplink)", HFILL }
528 { &hf_pgsl_ccu_ta,
529 { "CCU TA Value", "gsm_abis_pgsl.ccu_ta",
530 FT_UINT8, BASE_DEC, NULL, 0x3f,
531 NULL, HFILL }
533 { &hf_pgsl_ack_req,
534 { "ACK Requested", "gsm_abis_pgsl.ack_req",
535 FT_BOOLEAN, 8, NULL, 0x01,
536 NULL, HFILL }
538 { &hf_pgsl_tn_resource,
539 { "TN Resource", "gsm_abis_pgsl.tn_resource",
540 FT_UINT8, BASE_DEC, NULL, 0x07,
541 "Timeslot Number", HFILL }
543 { &hf_pgsl_tn_seqno,
544 { "TN Sequence Number", "gsm_abis_pgsl.tn_seqno",
545 FT_UINT8, BASE_DEC, NULL, 0,
546 "Per-TN Sequence Number", HFILL }
548 { &hf_pgsl_data_len,
549 { "Data Length", "gsm_abis_pgsl.data_len",
550 FT_UINT8, BASE_DEC, NULL, 0,
551 NULL, HFILL }
553 { &hf_pgsl_cause,
554 { "Cause", "gsm_abis_pgsl.cause",
555 FT_UINT8, BASE_DEC, VALS(pgsl_msg_cause_vals), 0,
556 NULL, HFILL }
558 { &hf_pgsl_addl_info,
559 { "Additional Info", "gsm_abis_pgsl.addl_info",
560 FT_UINT8, BASE_HEX, NULL, 0,
561 NULL, HFILL }
563 { &hf_pgsl_ack_ind,
564 { "ACK Indicator", "gsm_abis_pgsl.ack_ind",
565 FT_BOOLEAN, 8, NULL, 0x02,
566 NULL, HFILL }
568 { &hf_pgsl_data_ind,
569 { "Data Indicator", "gsm_abis_pgsl.data_ind",
570 FT_BOOLEAN, 8, NULL, 0x01,
571 NULL, HFILL }
573 { &hf_pgsl_ucm,
574 { "Uplink Channel Mode", "gsm_abis_pgsl.ucm",
575 FT_UINT8, BASE_DEC, VALS(pgsl_ucm_vals), 0xe0,
576 NULL, HFILL }
578 { &hf_pgsl_cs,
579 { "Coding Scheme", "gsm_abis_pgsl.cs",
580 FT_UINT8, BASE_DEC, VALS(pgsl_cs_vals), 0x1f,
581 NULL, HFILL }
583 { &hf_pgsl_timing_offset,
584 { "Timing Offset", "gsm_abis_pgsl.timing_offset",
585 FT_UINT8, BASE_DEC, NULL, 0,
586 NULL, HFILL }
588 { &hf_pgsl_power_control,
589 { "Power Control", "gsm_abis_pgsl.power_control",
590 FT_UINT8, BASE_DEC, NULL, 0x0f,
591 NULL, HFILL }
593 { &hf_pgsl_ir_tfi,
594 { "TFI", "gsm_abis_pgsl.ir_tfi",
595 FT_UINT8, BASE_DEC, NULL, 0x7c,
596 "TBF Identifier", HFILL }
598 { &hf_pgsl_ir_sign_type,
599 { "IR Signalling Type", "gsm_abis_pgsl.ir_sign_type",
600 FT_UINT8, BASE_DEC, VALS(pgsl_ir_sign_type_vals), 0x03,
601 NULL, HFILL }
603 { &hf_pgsl_codec_delay,
604 { "Codec Delay", "gsm_abis_pgsl.codec_delay",
605 FT_UINT8, BASE_DEC, NULL, 0xe0,
606 "Estimated Access Delay Deviation", HFILL }
608 { &hf_pgsl_codec_cs,
609 { "Codec CS", "gsm_abis_pgsl.codec_csy",
610 FT_UINT8, BASE_DEC, VALS(pgsl_cs_vals), 0x1f,
611 "Coding Scheme Status", HFILL }
613 { &hf_pgsl_codec_rxlev,
614 { "RxLev", "gsm_abis_pgsl.codec_rxlev",
615 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &gsm_a_rr_rxlev_vals_ext, 0x3f,
616 "Receiver Level Measurement", HFILL }
618 { &hf_pgsl_codec_parity,
619 { "GPRS Parity", "gsm_abis_pgsl.gprs_parity",
620 FT_BOOLEAN, 8, NULL, 0x08,
621 "GPRS Block Status Parity", HFILL }
623 { &hf_pgsl_codec_bqm,
624 { "GPRS BQM", "gsm_abis_pgsl.gprs_bqm",
625 FT_UINT8, BASE_DEC, NULL, 0x07,
626 "GPRS Block Quality Measurement", HFILL }
628 { &hf_pgsl_codec_mean_bep,
629 { "EGPRS MEAN_BEP", "gsm_abis_pgsl.egprs_mean_bep",
630 FT_UINT8, BASE_DEC, NULL, 0x7f,
631 "Mean Value of BEP", HFILL }
633 { &hf_pgsl_codec_cv_bep,
634 { "EGPRS CV_BEP", "gsm_abis_pgsl.egprs_cv_bep",
635 FT_UINT8, BASE_DEC, NULL, 0x07,
636 "Variation Co-Efficient of BEP", HFILL }
638 { &hf_pgsl_codec_q,
639 { "EGPRS Header Quality", "gsm_abis_pgsl.egprs_q",
640 FT_BOOLEAN, 8, TFS(&pgsl_q_vals), 0x08,
641 "EGPRS RLC/MAC Header Quality", HFILL }
643 { &hf_pgsl_codec_q1,
644 { "EGPRS Data Block 1 Quality", "gsm_abis_pgsl.egprs_q1",
645 FT_BOOLEAN, 8, TFS(&pgsl_q_vals), 0x10,
646 NULL, HFILL }
648 { &hf_pgsl_codec_q2,
649 { "EGPRS Data Block 2 Quality", "gsm_abis_pgsl.egprs_q2",
650 FT_BOOLEAN, 8, TFS(&pgsl_q_vals), 0x20,
651 NULL, HFILL }
653 { &hf_pgsl_pacch,
654 { "PACCH", "gsm_abis_pgsl.pacch",
655 FT_NONE, BASE_NONE, NULL, 0,
656 NULL, HFILL }
658 { &hf_pgsl_ab_rxlev,
659 { "Access Burst Rx Level", "gsm_abis_pgsl.ab.rxlev",
660 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &gsm_a_rr_rxlev_vals_ext, 0,
661 NULL, HFILL }
663 { &hf_pgsl_ab_acc_delay,
664 { "Access Burst Access Delay", "gsm_abis_pgsl.ab.acc_delay",
665 FT_UINT16, BASE_DEC, NULL, 0,
666 NULL, HFILL }
668 { &hf_pgsl_ab_abi,
669 { "Access Burst Indicator", "gsm_abis_pgsl.ab.abi",
670 FT_UINT8, BASE_DEC, VALS(pgsl_ab_abi_vals), 0x70,
671 NULL, HFILL }
673 { &hf_pgsl_ab_ab_type,
674 { "Access Burst Type", "gsm_abis_pgsl.ab.type",
675 FT_UINT8, BASE_DEC, VALS(pgsl_ab_type_vals), 0x0c,
676 NULL, HFILL }
679 static int *ett[] = {
680 &ett_pgsl,
681 &ett_pacch,
683 module_t *pgsl_module;
685 /* assign our custom match functions */
686 proto_abis_pgsl = proto_register_protocol("GSM A-bis P-GSL", "Ericsson GSM A-bis P-GSL",
687 "gsm_abis_pgsl");
688 pgsl_module = prefs_register_protocol(proto_abis_pgsl, NULL);
689 prefs_register_bool_preference(pgsl_module, "ir",
690 "Incremental Redundancy",
691 "The packets contain the optional Incremental Redundancy (IR) fields",
692 &abis_pgsl_ir);
694 proto_register_field_array(proto_abis_pgsl, hf, array_length(hf));
695 proto_register_subtree_array(ett, array_length(ett));
696 pgsl_handle = register_dissector("gsm_abis_pgsl", dissect_abis_pgsl, proto_abis_pgsl);
699 /* This function is called once at startup and every time the user hits
700 * 'apply' in the preferences dialogue */
701 void
702 proto_reg_handoff_abis_pgsl(void)
704 /* The SAPI value 12 is a non-standard values, not specified by
705 * ETSI/3GPP, just like this very same protocol. */
706 dissector_add_uint("lapd.gsm.sapi", 12, pgsl_handle);
708 sub_handles[SUB_RLCMAC_UL] = find_dissector("gsm_rlcmac_ul");
709 sub_handles[SUB_RLCMAC_DL] = find_dissector("gsm_rlcmac_dl");
713 * Editor modelines - https://www.wireshark.org/tools/modelines.html
715 * Local variables:
716 * c-basic-offset: 8
717 * tab-width: 8
718 * indent-tabs-mode: t
719 * End:
721 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
722 * :indentSize=8:tabSize=8:noTabs=false: