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
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
19 #include <epan/packet.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);
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
;
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 */
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" },
99 static const true_false_string pgsl_q_vals
= {
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" },
112 static const value_string pgsl_cs_vals
[] = {
118 { 5, "Header Type 1" },
119 { 6, "Header Type 2" },
120 { 7, "Header Type 3" },
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)" },
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" },
140 static const value_string pgsl_ab_type_vals
[] = {
142 { 1, "11-bit RACH (TS0)" },
143 { 2, "11-bit RACH (TS1)" },
144 { 3, "11-bit RACH (TS2)" },
148 static const value_string pgsl_ab_abi_vals
[] = {
154 static RLCMAC_block_format_t
pgsl_cs_to_rlcmac_cs(uint8_t pgsl_cs
)
156 static const RLCMAC_block_format_t tbl
[8] = {
173 /* length of an EGPRS RLC data block for given MCS */
174 static const unsigned data_block_len_by_mcs
[] = {
188 /* determine the number of rlc data blocks and their size / offsets */
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
:
201 dbo
[0] = is_uplink
? 5*8 + 6 : 5*8 + 0;
202 dbo
[1] = dbo
[0] + dbl
* 8 + 2;
204 case RLCMAC_HDR_TYPE_2
:
206 dbo
[0] = is_uplink
? 4*8 + 5 : 3*8 + 4;
208 case RLCMAC_HDR_TYPE_3
:
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
)
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
);
246 src
= src
+ hdr_bytes
;
249 for (i
= 0; i
< length_bytes
; i
++) {
251 *(dst
++) = (last_c
>> extra_bits
) | (c
<< (8 - extra_bits
));
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
),
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");
287 /* Dissect a P-GSL ACess Burst Message */
289 dissect_pgsl_access_burst(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
,
290 RlcMacPrivateData_t
*rlcmac_data
)
293 proto_tree
*pacch_tree
;
295 unsigned rxlev
, abtype
, abi
;
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 */
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
);
313 /* Update the 'master' item */
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
);
322 proto_item_append_text(ti
, " Invalid, RxLev %u", rxlev
);
325 /* Dissect a given (E)GPRS RLC/MAC block */
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
;
332 unsigned data_block_bits
, data_block_offsets
[2];
336 rlcmac_dissector
= sub_handles
[SUB_RLCMAC_UL
];
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
) {
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
);
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
);
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
382 call_dissector_with_data(rlcmac_dissector
, tvb
, pinfo
, tree
,
383 (void *) rlcmac_data
);
388 dissect_abis_pgsl(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
391 proto_tree
*pgsl_tree
;
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
);
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
;
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
);
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
);
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
;
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) {
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
);
435 proto_tree_add_item(pgsl_tree
, hf_pgsl_power_control
, tvb
, offset
++, 1, ENC_NA
);
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
);
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
);
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
;
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
);
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
);
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
);
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
);
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
);
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
);
495 proto_register_abis_pgsl(void)
497 static hf_register_info hf
[] = {
499 { "Version", "gsm_abis_pgsl.version",
500 FT_UINT8
, BASE_DEC
, NULL
, 0xf0,
504 { "Message Discriminator", "gsm_abis_pgsl.msg_disc",
505 FT_UINT8
, BASE_DEC
, VALS(pgsl_msg_disc_vals
), 0x0f,
508 { &hf_pgsl_tn_bitmap
,
509 { "TN Bitmap", "gsm_abis_pgsl.tn_bitmap",
510 FT_UINT8
, BASE_HEX
, NULL
, 0,
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
}
519 { "aFNd", "gsm_abis_pgsl.a_fn_d",
520 FT_UINT24
, BASE_DEC
, NULL
, 0,
521 "Frame Number (Downlink)", HFILL
}
524 { "aFNu", "gsm_abis_pgsl.a_fn_u",
525 FT_UINT24
, BASE_DEC
, NULL
, 0,
526 "Frame Number (Uplink)", HFILL
}
529 { "CCU TA Value", "gsm_abis_pgsl.ccu_ta",
530 FT_UINT8
, BASE_DEC
, NULL
, 0x3f,
534 { "ACK Requested", "gsm_abis_pgsl.ack_req",
535 FT_BOOLEAN
, 8, NULL
, 0x01,
538 { &hf_pgsl_tn_resource
,
539 { "TN Resource", "gsm_abis_pgsl.tn_resource",
540 FT_UINT8
, BASE_DEC
, NULL
, 0x07,
541 "Timeslot Number", HFILL
}
544 { "TN Sequence Number", "gsm_abis_pgsl.tn_seqno",
545 FT_UINT8
, BASE_DEC
, NULL
, 0,
546 "Per-TN Sequence Number", HFILL
}
549 { "Data Length", "gsm_abis_pgsl.data_len",
550 FT_UINT8
, BASE_DEC
, NULL
, 0,
554 { "Cause", "gsm_abis_pgsl.cause",
555 FT_UINT8
, BASE_DEC
, VALS(pgsl_msg_cause_vals
), 0,
558 { &hf_pgsl_addl_info
,
559 { "Additional Info", "gsm_abis_pgsl.addl_info",
560 FT_UINT8
, BASE_HEX
, NULL
, 0,
564 { "ACK Indicator", "gsm_abis_pgsl.ack_ind",
565 FT_BOOLEAN
, 8, NULL
, 0x02,
569 { "Data Indicator", "gsm_abis_pgsl.data_ind",
570 FT_BOOLEAN
, 8, NULL
, 0x01,
574 { "Uplink Channel Mode", "gsm_abis_pgsl.ucm",
575 FT_UINT8
, BASE_DEC
, VALS(pgsl_ucm_vals
), 0xe0,
579 { "Coding Scheme", "gsm_abis_pgsl.cs",
580 FT_UINT8
, BASE_DEC
, VALS(pgsl_cs_vals
), 0x1f,
583 { &hf_pgsl_timing_offset
,
584 { "Timing Offset", "gsm_abis_pgsl.timing_offset",
585 FT_UINT8
, BASE_DEC
, NULL
, 0,
588 { &hf_pgsl_power_control
,
589 { "Power Control", "gsm_abis_pgsl.power_control",
590 FT_UINT8
, BASE_DEC
, NULL
, 0x0f,
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,
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
}
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
}
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
}
644 { "EGPRS Data Block 1 Quality", "gsm_abis_pgsl.egprs_q1",
645 FT_BOOLEAN
, 8, TFS(&pgsl_q_vals
), 0x10,
649 { "EGPRS Data Block 2 Quality", "gsm_abis_pgsl.egprs_q2",
650 FT_BOOLEAN
, 8, TFS(&pgsl_q_vals
), 0x20,
654 { "PACCH", "gsm_abis_pgsl.pacch",
655 FT_NONE
, BASE_NONE
, NULL
, 0,
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,
663 { &hf_pgsl_ab_acc_delay
,
664 { "Access Burst Access Delay", "gsm_abis_pgsl.ab.acc_delay",
665 FT_UINT16
, BASE_DEC
, NULL
, 0,
669 { "Access Burst Indicator", "gsm_abis_pgsl.ab.abi",
670 FT_UINT8
, BASE_DEC
, VALS(pgsl_ab_abi_vals
), 0x70,
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,
679 static int *ett
[] = {
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",
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",
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 */
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
718 * indent-tabs-mode: t
721 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
722 * :indentSize=8:tabSize=8:noTabs=false: