diff options
author | Anders Broman <anders.broman@ericsson.com> | 2011-03-07 09:36:24 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2011-03-07 09:36:24 +0000 |
commit | a7e379499d0470aad7d432015870eb5edbd787dd (patch) | |
tree | b32d2a1d174281c3597e58af6d91e9d1b278e7b5 /epan/dissectors/packet-bssgp.c | |
parent | 3e92ea5c2fe6e938c7d9fff0c8cb4ac6dcdddad8 (diff) |
Remove the old code.
svn path=/trunk/; revision=36152
Diffstat (limited to 'epan/dissectors/packet-bssgp.c')
-rw-r--r-- | epan/dissectors/packet-bssgp.c | 5989 |
1 files changed, 80 insertions, 5909 deletions
diff --git a/epan/dissectors/packet-bssgp.c b/epan/dissectors/packet-bssgp.c index 230aba20fd..18f58d705f 100644 --- a/epan/dissectors/packet-bssgp.c +++ b/epan/dissectors/packet-bssgp.c @@ -102,15 +102,9 @@ static dissector_handle_t data_handle; static module_t *bssgp_module; /* Initialize the protocol and registered fields */ -static int hf_bssgp_iei_nacc_cause = -1; static int proto_bssgp = -1; static int hf_bssgp_msg_type = -1; int hf_bssgp_elem_id = -1; -static int hf_bssgp_ie_type = -1; -static int hf_bssgp_mcc = -1; -static int hf_bssgp_mnc = -1; -static int hf_bssgp_lac = -1; -static int hf_bssgp_rac = -1; static int hf_bssgp_ci = -1; static int hf_bssgp_flush_action = -1; static int hf_bssgp_llc_frames_disc = -1; @@ -128,24 +122,17 @@ static int hf_bssgp_ran_inf_req_pdu_t_ext_c = -1; static int hf_bssgp_ran_inf_pdu_t_ext_c = -1; static int hf_bssgp_rim_pdu_ind_ack = -1; static int hf_bssgp_rim_proto_ver_no = -1; -static int hf_bssgp_rcid = -1; -static int hf_bssgp_rrc_si_msg_type = -1; -static int hf_ran_inf_req_pdu_type_ext = -1; -static int hf_ran_inf_pdu_type_ext = -1; -static int hf_bssgp_nri = -1; -static int hf_bssgp_imsi = -1; -static int hf_bssgp_imei = -1; -static int hf_bssgp_imeisv = -1; static int hf_bssgp_tmsi_ptmsi = -1; static int hf_bssgp_bss_area_ind = -1; static int hf_bssgp_bvci = -1; static int hf_bssgp_bmax = -1; static int hf_bssgp_r = -1; +static int hf_bssgp_r_pfc = -1; static int hf_bssgp_bucket_size = -1; +static int hf_bssgp_bmax_pfc = -1; static int hf_bssgp_omc_id = -1; static int hf_bssgp_nsei = -1; static int hf_bssgp_rrlp_flag1 = -1; -static int hf_bssgp_tlli = -1; static int hf_bssgp_delay_val = -1; static int hf_bssgp_cause = -1; @@ -173,6 +160,7 @@ static int hf_bssgp_inr = -1; static int hf_bssgp_cbl = -1; static int hf_bssgp_pfc = -1; static int hf_bssgp_bucket_full_ratio = -1; +static int hf_bssgp_b_pfc = -1; static int hf_bssgp_precedence = -1; static int hf_bssgp_serv_utran_cco = -1; @@ -203,56 +191,13 @@ static int hf_bssgp_SONtransferRequestContainer_PDU = -1; /* Initialize the subtree pointers */ static gint ett_bssgp = -1; static gint ett_bssgp_new = -1; -static gint ett_bssgp_qos_profile = -1; -static gint ett_bssgp_gprs_timer = -1; -static gint ett_bssgp_cell_identifier = -1; -static gint ett_bssgp_channel_needed = -1; -static gint ett_bssgp_drx_parameters = -1; -static gint ett_bssgp_mobile_identity = -1; -static gint ett_bssgp_priority = -1; -static gint ett_bssgp_lsa_identifier_list = -1; -static gint ett_bssgp_lsa_information = -1; -static gint ett_bssgp_lsa_information_lsa_identification_and_attributes = -1; -static gint ett_bssgp_abqp = -1; -static gint ett_bssgp_lcs_qos = -1; -static gint ett_bssgp_lcs_client_type = -1; -static gint ett_bssgp_requested_gps_assistance_data = -1; -static gint ett_bssgp_requested_gps_assistance_data_satellite = -1; -static gint ett_bssgp_location_type = -1; -static gint ett_bssgp_positioning_data_positioning_method = -1; -static gint ett_bssgp_deciphering_keys = -1; -static gint ett_bssgp_lcs_cause = -1; -static gint ett_bssgp_lcs_capability = -1; -static gint ett_bssgp_rrlp_flags = -1; -static gint ett_bssgp_rim_pdu_indications = -1; -static gint ett_bssgp_mcc = -1; -static gint ett_bssgp_mnc = -1; -static gint ett_bssgp_routing_area = -1; -static gint ett_bssgp_location_area = -1; -static gint ett_bssgp_rai_ci = -1; -static gint ett_bssgp_rim_routing_information =-1; -static gint ett_bssgp_ran_information_request_application_container = -1; -static gint ett_bssgp_ran_information_request_container_unit = -1; -static gint ett_bssgp_ran_information_container_unit = -1; -static gint ett_bssgp_pfc_flow_control_parameters = -1; -static gint ett_bssgp_pfc_flow_control_parameters_pfc = -1; -static gint ett_bssgp_global_cn_id = -1; -static gint ett_bssgp_ms_radio_access_capability = -1; -static gint ett_bssgp_msrac_value_part = -1; -static gint ett_bssgp_msrac_additional_access_technologies = -1; -static gint ett_bssgp_msrac_access_capabilities = -1; -static gint ett_bssgp_msrac_a5_bits = -1; -static gint ett_bssgp_msrac_multislot_capability = -1; -static gint ett_bssgp_feature_bitmap = -1; -static gint ett_bssgp_positioning_data = -1; -static gint ett_bssgp_tlli = -1; -static gint ett_bssgp_tmsi_ptmsi = -1; static gint ett_bssgp_pfcs_to_be_set_up_list = -1; static gint ett_bssgp_pfcs_to_be_set_up_list_pft = -1; static gint ett_bssgp_pfcs_to_be_set_up_list_abqp = -1; static gint ett_bssgp_pfcs_to_be_set_up_list_arp = -1; static gint ett_bssgp_pfcs_to_be_set_up_list_t10 = -1; static gint ett_bssgp_list_of_setup_pfcs = -1; +static gint ett_bssgp_pfc_flow_control_parameters_pfc = -1; /* PDU type coding, v6.5.0, table 11.3.26, p 80 */ #define BSSGP_PDU_DL_UNITDATA 0x00 @@ -408,85 +353,6 @@ static gint ett_bssgp_list_of_setup_pfcs = -1; 0x92 PS-HANDOVER-CANCEL 0x93 PS-HANDOVER-COMPLETE-ACK */ -static const value_string tab_bssgp_pdu_types[] = { -/* 0x00 */ { BSSGP_PDU_DL_UNITDATA, "DL-UNITDATA" }, -/* 0x01 */ { BSSGP_PDU_UL_UNITDATA, "UL-UNITDATA" }, -/* 0x02 */ { BSSGP_PDU_RA_CAPABILITY, "RA-CAPABILITY" }, -/* 0x03 */ { BSSGP_PDU_PTM_UNITDATA, "PTM-UNITDATA" }, -/* 0x04 */ { BSSGP_PDU_DL_MBMS_UNITDATA, "DL-MBMS-UNITDATA" }, -/* 0x05 */ { BSSGP_PDU_UL_MBMS_UNITDATA, "UL-MBMS-UNITDATA" }, -/* 0x06 */ { BSSGP_PDU_PAGING_PS, "PAGING-PS" }, -/* 0x07 */ { BSSGP_PDU_PAGING_CS, "PAGING-CS" }, -/* 0x08 */ { BSSGP_PDU_RA_CAPABILITY_UPDATE, "RA-CAPABILITY-UPDATE" }, -/* 0x09 */ { BSSGP_PDU_RA_CAPABILITY_UPDATE_ACK, "RA-CAPABILITY-UPDATE-ACK" }, -/* 0x0a */ { BSSGP_PDU_RADIO_STATUS, "RADIO-STATUS" }, -/* 0x0b */ { BSSGP_PDU_SUSPEND, "SUSPEND" }, -/* 0x0c */ { BSSGP_PDU_SUSPEND_ACK, "SUSPEND-ACK" }, -/* 0x0d */ { BSSGP_PDU_SUSPEND_NACK, "SUSPEND-NACK" }, -/* 0x0e */ { BSSGP_PDU_RESUME, "RESUME" }, -/* 0x0f */ { BSSGP_PDU_RESUME_ACK, "RESUME-ACK" }, -/* 0x10 */ { BSSGP_PDU_RESUME_NACK, "RESUME-NACK" }, - /* 0x11 to 0x1f Reserved */ -/* 0x20 */ { BSSGP_PDU_BVC_BLOCK, "BVC-BLOCK" }, -/* 0x21 */ { BSSGP_PDU_BVC_BLOCK_ACK, "BVC-BLOCK-ACK" }, -/* 0x22 */ { BSSGP_PDU_BVC_RESET, "BVC-RESET" }, -/* 0x23 */ { BSSGP_PDU_BVC_RESET_ACK, "BVC-RESET-ACK" }, -/* 0x24 */ { BSSGP_PDU_BVC_UNBLOCK, "UNBLOCK" }, -/* 0x25 */ { BSSGP_PDU_BVC_UNBLOCK_ACK, "UNBLOCK-ACK" }, -/* 0x26 */ { BSSGP_PDU_FLOW_CONTROL_BVC, "FLOW-CONTROL-BVC" }, -/* 0x27 */ { BSSGP_PDU_FLOW_CONTROL_BVC_ACK, "FLOW-CONTROL-BVC-ACK" }, -/* 0x28 */ { BSSGP_PDU_FLOW_CONTROL_MS, "FLOW-CONTROL-MS" }, -/* 0x29 */ { BSSGP_PDU_FLOW_CONTROL_MS_ACK, "FLOW-CONTROL-MS-ACK" }, -/* 0x2a */ { BSSGP_PDU_FLUSH_LL, "FLUSH-LL" }, -/* 0x2b */ { BSSGP_PDU_FLUSH_LL_ACK, "FLUSH_LL_ACK" }, -/* 0x2c */ { BSSGP_PDU_LLC_DISCARDED, "LLC-DISCARDED" }, -/* 0x2d */ { BSSGP_PDU_FLOW_CONTROL_PFC, "FLOW-CONTROL-PFC" }, -/* 0x2e */ { BSSGP_PDU_FLOW_CONTROL_PFC_ACK, "FLOW-CONTROL-PFC-ACK" }, - /* 0x2f to 0x3f Reserved */ - -/* 0x40 */ { BSSGP_PDU_SGSN_INVOKE_TRACE, "SGSN-INVOKE-TRACE" }, -/* 0x41 */ { BSSGP_PDU_STATUS, "STATUS" }, - /* 0x42 to 0x4f Reserved */ -/* 0x50 */ { BSSGP_PDU_DOWNLOAD_BSS_PFC, "DOWNLOAD-BSS-PFC" }, -/* 0x51 */ { BSSGP_PDU_CREATE_BSS_PFC, "CREATE-BSS-PFC" }, -/* 0x52 */ { BSSGP_PDU_CREATE_BSS_PFC_ACK, "CREATE-BSS-PFC-ACK" }, -/* 0x53 */ { BSSGP_PDU_CREATE_BSS_PFC_NACK, "CREATE-BSS-PFC-NACK" }, -/* 0x54 */ { BSSGP_PDU_MODIFY_BSS_PFC, "MODIFY-BSS-PFC" }, -/* 0x55 */ { BSSGP_PDU_MODIFY_BSS_PFC_ACK, "MODIFY-BSS-PFC-ACK" }, -/* 0x56 */ { BSSGP_PDU_DELETE_BSS_PFC, "DELETE-BSS-PFC" }, -/* 0x57 */ { BSSGP_PDU_DELETE_BSS_PFC_ACK, "DELETE-BSS-PFC-ACK" }, -/* 0x58 */ { BSSGP_PDU_DELETE_BSS_PFC_REQ, "DELETE-BSS-PFC-REQ" }, -/* 0x59 */ { BSSGP_PDU_PS_HANDOVER_REQUIRED, "PS-HANDOVER-REQUIRED" }, -/* 0x5a */ { BSSGP_PDU_PS_HANDOVER_REQUIRED_ACK, "PS-HANDOVER-REQUIRED-ACK" }, -/* 0x5b */ { BSSGP_PDU_PS_HANDOVER_REQUIRED_NACK, "PS-HANDOVER-REQUIRED-NACK" }, -/* 0x5c */ { BSSGP_PDU_PS_HANDOVER_REQUEST, "PS-HANDOVER-REQUEST" }, -/* 0x5d */ { BSSGP_PDU_PS_HANDOVER_REQUEST_ACK, "PS-HANDOVER-REQUEST-ACK" }, -/* 0x5e */ { BSSGP_PDU_PS_HANDOVER_REQUEST_NACK, "PS-HANDOVER-REQUEST-NACK" }, - -/* 0x60 */ { BSSGP_PDU_PERFORM_LOCATION_REQUEST, "PERFORM-LOCATION-REQUEST" }, -/* 0x61 */ { BSSGP_PDU_PERFORM_LOCATION_RESPONSE, "PERFORM-LOCATION-RESPONSE" }, -/* 0x62 */ { BSSGP_PDU_PERFORM_LOCATION_ABORT, "PERFORM-LOCATION-ABORT" }, -/* 0x63 */ { BSSGP_PDU_POSITION_COMMAND, "POSITION-COMMAND" }, -/* 0x64 */ { BSSGP_PDU_POSITION_RESPONSE, "POSITION-RESPONSE" }, - -/* 0x70 */ { BSSGP_PDU_RAN_INFORMATION, "RAN-INFORMATION" }, -/* 0x71 */ { BSSGP_PDU_RAN_INFORMATION_REQUEST, "RAN-INFORMATION-REQUEST" }, -/* 0x72 */ { BSSGP_PDU_RAN_INFORMATION_ACK, "RAN-INFORMATION-ACK" }, -/* 0x73 */ { BSSGP_PDU_RAN_INFORMATION_ERROR, "RAN-INFORMATION-ERROR" }, -/* 0x74 */ { BSSGP_PDU_RAN_INFORMATION_APP_ERROR, "RAN-INFORMATION-APPLICATION-ERROR" }, - -/* 0x80 */ {0x80, "MBMS-SESSION-START-REQUEST" }, -/* 0x81 */ {0x81, "MBMS-SESSION-START-RESPONSE" }, -/* 0x82 */ {0x82, "MBMS-SESSION-STOP-REQUEST" }, -/* 0x83 */ {0x83, "MBMS-SESSION-STOP-RESPONSE" }, -/* 0x84 */ {0x84, "MBMS-SESSION-UPDATE-REQUEST" }, -/* 0x85 */ {0x85, "MBMS-SESSION-UPDATE-RESPONSE" }, - -/* 0x91 */ {0x91, "PS-HANDOVER-COMPLETE" }, -/* 0x92 */ {0x92, "PS-HANDOVER-CANCEL" }, -/* 0x93 */ {0x93, "PS-HANDOVER-COMPLETE-ACK" }, - { 0, NULL }, -}; /* Information element coding, v 6.5.0, table 11.3, p 72 */ #define BSSGP_IEI_ALIGNMENT_OCTETS 0x00 @@ -743,5569 +609,7 @@ static const value_string tab_bssgp_ie_types[] = { { 0, NULL }, }; -/* Presence requirements of Information Elements - 48.016 v 5.3.0, chapter 8.1.1, p. 35 */ -#define BSSGP_IE_PRESENCE_M 1 /* Mandatory */ -#define BSSGP_IE_PRESENCE_C 2 /* Conditional */ -#define BSSGP_IE_PRESENCE_O 3 /* Optional */ - -/* Format options */ -#define BSSGP_IE_FORMAT_V 1 -#define BSSGP_IE_FORMAT_TV 2 -#define BSSGP_IE_FORMAT_TLV 3 - - -static guint8 -get_masked_guint8(guint8 value, guint8 mask) { - const guint8 MASK_BIT_1 = 0x01; - guint8 i = 0; - - while (!((mask >> i) & MASK_BIT_1)) { - i++; - if (i > 7) return 0; - } - return (value & mask) >> i; -} - -#if 0 -static guint16 -get_masked_guint16(guint16 value, guint16 mask) { - const guint16 MASK_BIT_1 = 0x01; - guint8 i = 0; - - while (!((mask >> i) & MASK_BIT_1)) { - i++; - if (i > 15) return 0; - } - return (value & mask) >> i; -} -#endif - -static gint32 -make_mask32(guint8 num_bits, guint8 shift_value) { - const guint32 LEFT_MOST_1 = 0x80000000; - int i; - guint32 mask = LEFT_MOST_1; - - for (i = 0; i < (num_bits - 1); i++) { - mask = (mask >> 1) | LEFT_MOST_1; - } - return mask >> shift_value; -} - -static guint32 -get_masked_guint32(guint32 value, guint32 mask) { - const guint16 MASK_BIT_1 = 0x01; - guint8 i = 0; - - while (!((mask >> i) & MASK_BIT_1)) { - i++; - if (i > 31) return 0; - } - return (value & mask) >> i; -} - -static guint8 -tvb_get_masked_guint8(tvbuff_t *tvb, int offset, guint8 mask) { - guint8 value = tvb_get_guint8(tvb, offset); - return get_masked_guint8(value, mask); -} - -static char* -get_bit_field_label(guint16 value, guint16 value_mask, guint16 num_bits) { -#define MAX_NUM_BITS 16 - guint16 i, bit_mask; - static char label[MAX_NUM_BITS + 1]; - - DISSECTOR_ASSERT(num_bits <= MAX_NUM_BITS); - for (i = 0; i < num_bits; i++) { - bit_mask = 1 << i; - if (value_mask & bit_mask) { - label[num_bits - 1 - i] = (value & bit_mask) ? '1' : '0'; - } - else { - label[num_bits - 1 - i] = '.'; - } - } -#undef MAX_NUM_BITS - return label; -} - -static char* -get_bit_field_label8(guint8 value, guint8 value_mask) { - char *bits; - static char formatted_label[10]; - bits = get_bit_field_label(value, value_mask, 8); - g_snprintf(formatted_label, 10, "%c%c%c%c %c%c%c%c", - bits[0], bits[1], bits[2], bits[3], - bits[4], bits[5], bits[6], bits[7]); - return formatted_label; -} - -static char* -get_bit_field_label16(guint16 value, guint16 value_mask) { - char *bits; - static char formatted_label[18]; - bits = get_bit_field_label(value, value_mask, 16); - g_snprintf(formatted_label, 18, "%c%c%c%c%c%c%c%c %c%c%c%c%c%c%c%c", - bits[0], bits[1], bits[2], bits[3], - bits[4], bits[5], bits[6], bits[7], - bits[8], bits[9], bits[10], bits[11], - bits[12], bits[13], bits[14], bits[15]); - return formatted_label; -} - -static proto_item * -proto_tree_add_bitfield8(proto_tree *tree, tvbuff_t *tvb, int offset, guint8 mask) { - /* XXX: Use varargs */ - guint8 value = tvb_get_guint8(tvb, offset); - char *label = get_bit_field_label8(value, mask); - proto_item *pi = proto_tree_add_text(tree, tvb, offset, 1, "%s = ", - label); - return pi; -} - -#if 0 -static proto_item * -proto_tree_add_bitfield16(proto_tree *tree, tvbuff_t *tvb, int offset, guint16 mask) { - /* XXX: Use varargs */ - guint16 value = tvb_get_ntohs(tvb, offset); - char *label = get_bit_field_label16(value, mask); - proto_item *pi = proto_tree_add_text(tree, tvb, offset, 2, "%s = ", - label); - return pi; -} -#endif - -static guint8 -get_byte_offset(guint32 bo) { - return (guint8) bo % 8; -} - -static guint32 -get_end_octet(guint32 bo, guint32 bl) -{ - return (guint32) ceil((bo + bl) / 8.0); -} - -static guint32 -get_num_octets_spanned(guint32 bo, guint32 bl) -{ - return get_end_octet(bo, bl) - (bo >> 3); -} - -static gint16 -make_mask(guint8 num_bits, guint8 shift_value) { - guint16 mask; - - switch (num_bits) { - case 0: mask = 0x0000; break; - case 1: mask = 0x8000; break; - case 2: mask = 0xc000; break; - case 3: mask = 0xe000; break; - case 4: mask = 0xf000; break; - case 5: mask = 0xf800; break; - case 6: mask = 0xfc00; break; - case 7: mask = 0xfe00; break; - case 8: mask = 0xff00; break; - default: DISSECTOR_ASSERT_NOT_REACHED(); mask = 0; break; - } - return mask >> shift_value; -} - -static proto_item * -bit_proto_tree_add_text(proto_tree *tree, tvbuff_t *tvb, - guint32 bo, guint8 bl, const char *value) { - /* XXX: Use varargs */ - return proto_tree_add_text(tree, tvb, bo >> 3, - get_num_octets_spanned(bo, bl), "%s", value); -} - -static proto_item * -bit_proto_tree_add_bit_field8(proto_tree *tree, tvbuff_t *tvb, - guint32 bo, guint8 bl) { - /* XXX: Use varargs */ - guint16 mask = make_mask(bl, get_byte_offset(bo)); - guint16 value; - guint8 end_i; - int i; - proto_item *pi; - char *label; - if (( mask & 0xff ) == 0 ) value = tvb_get_guint8 ( tvb , bo >> 3) << 8; - else value = tvb_get_ntohs(tvb, bo >> 3); - label = get_bit_field_label16(value, mask); - - DISSECTOR_ASSERT(bl < 9); - - if (get_num_octets_spanned(bo, bl) == 1) { - end_i = 7; - } - else { - end_i = 16; - } - pi = bit_proto_tree_add_text(tree, tvb, bo, bl, ""); - - for (i = 0; i <=end_i; i++) { - proto_item_append_text(pi, "%c", label[i]); - } - proto_item_append_text(pi, " = "); - return pi; -} - -static const char* -translate_abqp_reliability_class(guint8 value, build_info_t *bi) { - switch (value) { - case 0: - if (bi->ul_data) { - return "Subscribed reliability class"; - } - else { - return "Reserved"; - } - case 1: - return "Unused (Unacknowledged GTP; Acknowledged LLc and RLC, Protected data)"; - case 2: - return "Unacknowledged GTP; Acknowledged LLc and RLC, Protected data"; - case 3: - return "Unacknowledged GTP and LLC; Acknowledged RLC, Protected data"; - case 4: - return "Unacknowledged GTP, LLC, and RLC, Protected data"; - case 5: - return "Unacknowledged GTP, LLC, and RLC, Unprotedcted data"; - case 7: - return "Reserved"; - default: - return "Unacknowledged GTP and LLC; Acknowledged RLC, Protected data"; - } -} -static const char* -translate_abqp_delay_class(guint8 value, build_info_t *bi) { - switch (value) { - case 0: - if (bi->ul_data) { - return "Subscribed delay class"; - } - else { - return "Reserved"; - } - case 1: return "Delay class 1"; - case 2: return "Delay class 2"; - case 3: return "Delay class 3"; - case 4: return "Delay class 4 (best effort)"; - case 7: return "Reserved"; - default: - return "Delay class 4 (best effort)"; - } -} -static const char* -translate_abqp_peak_throughput(guint8 value, build_info_t *bi) { - switch (value) { - case 0: - if (bi->ul_data) { - return "Subscribed peak throughput"; - } - else { - return "Reserved"; - } - case 1: return "Up to 1 000 octets/s"; - case 2: return "Up to 2 000 octets/s"; - case 3: return "Up to 4 000 octets/s"; - case 4: return "Up to 8 000 octets/s"; - case 5: return "Up to 16 000 octets/s"; - case 6: return "Up to 32 000 octets/s"; - case 7: return "Up to 64 000 octets/s"; - case 8: return "Up to 128 000 octets/s"; - case 9: return "Up to 256 000 octets/s"; - case 15: return "Reserved"; - default: - return "Up to 1 000 octets/s"; - } -} -static const char* -translate_abqp_precedence_class(guint8 value, build_info_t *bi) { - switch (value) { - case 0: - if (bi->ul_data) { - return "Subscribed precedence"; - } - else { - return "Reserved"; - } - case 1: return "High priority"; - case 2: return "Normal priority"; - case 3: return "Low priority"; - case 7: return "Reserved"; - default: - return "Normal priority"; - } -} -static const char* -translate_abqp_mean_throughput(guint8 value, build_info_t *bi) { - switch (value) { - case 0: - if (bi->ul_data) { - return "Subscribed mean throughput"; - } - else { - return "Reserved"; - } - case 1: return "100 octets/h"; - case 2: return "200 octets/h"; - case 3: return "500 octets/h"; - case 4: return "1 000 octets/h"; - case 5: return "2 000 octets/h"; - case 6: return "5 000 octets/h"; - case 7: return "10 000 octets/h"; - case 8: return "20 000 octets/h"; - case 9: return "50 000 octets/h"; - case 0x0a: return "100 000 octets/h"; - case 0x0b: return "200 000 octets/h"; - case 0x0c: return "500 000 octets/h"; - case 0x0d: return "1 000 000 octets/h"; - case 0x0e: return "2 000 000 octets/h"; - case 0x0f: return "5 000 000 octets/h"; - case 0x10: return "10 000 000 octets/h"; - case 0x11: return "20 000 000 octets/h"; - case 0x12: return "50 000 000 octets/h"; - case 0x1e: return "Reserved"; - case 0x1f: return "Best effort"; - default: - return "Best effort"; - } -} -static const char* -translate_abqp_traffic_class(guint8 value, build_info_t *bi) { - switch (value) { - case 0: - if (bi->ul_data) { - return "Subscribed traffic class"; - } - else { - return "Reserved"; - } - case 1: return "Conversational class"; - case 2: return "Streaming class"; - case 3: return "Interactive class"; - case 4: return "Background class"; - case 7: return "Reserved"; - default: - if (bi->ul_data) { - /* The MS shall consider all other values as reserved */ - return "Reserved"; - } - else { - /* The network shall map all other values not explicitly defined onto one of the values defined in this version of the protocol. The network shall return a negotiated value which is explicitly defined in this version of the protocol */ - return "Error"; - } - } -} -static const char* -translate_abqp_delivery_order(guint8 value, build_info_t *bi) { - switch (value) { - case 0: - if (bi->ul_data) { - return "Subscribed delivery order"; - } - else { - return "Reserved"; - } - case 1: return "With delivery order ('yes')"; - case 2: return "Without delivery order ('no')"; - case 3: return "Reserved"; - default: - return "Error in BSSGP dissector"; - } -} -static const char* -translate_abqp_delivery_of_erroneous_sdu(guint8 value, build_info_t *bi) { - switch (value) { - case 0: - if (bi->ul_data) { - return "Subscribed delivery of erroneous SDUs"; - } - else { - return "Reserved"; - } - case 1: return "No detect ('-')"; - case 2: return "Erroneous SDUs are delivered ('yes')"; - case 3: return "Erroneous SDUs are not delivered ('no')"; - case 7: return "Reserved"; - default: - if (bi->ul_data) { - /* The MS shall consider all other values as reserved */ - return "Reserved"; - } - else { - /* The network shall map all other values not explicitly defined onto one of the values defined in this version of the protocol. The network shall return a negotiated value which is explicitly defined in this version of the protocol */ - return "Error"; - } - } -} -static const char* -translate_abqp_max_sdu_size(guint8 value, build_info_t *bi) { - static char result[BSSGP_TRANSLATION_MAX_LEN]; - - switch (value) { - case 0: - if (bi->ul_data) { - return "Subscribed maximum SDU size"; - } - else { - return "Reserved"; - } - case 0xff: - if (bi->ul_data) { - return "Reserved"; - } - else { - return "Reserved"; - } - case 0x97: return "1502 octets"; - case 0x98: return "1510 octets"; - case 0x99: return "1520 octets"; - } - if ((value >= 1) && (value <= 0x96)) { - g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u octets", value * 10); - return result; - } - if (bi->ul_data) { - /* The MS shall consider all other values as reserved */ - return "Reserved"; - } - else { - /* The network shall map all other values not explicitly defined onto one of the values defined in this version of the protocol. The network shall return a negotiated value which is explicitly defined in this version of the protocol */ - return "Error"; - } -} - -static const char* -translate_abqp_max_bit_rate_for_ul(guint8 value, build_info_t *bi) { - static char result[BSSGP_TRANSLATION_MAX_LEN]; - - if (value == 0) { - if (bi->ul_data) { - return "Subscribed maximum bit rate for uplink"; - } - else { - return "Reserved"; - } - } - if ((value >= 1) && (value <= 0x3f)) { - g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u kbps", value); - return result; - } - if ((value >= 0x40) && (value <= 0x7f)) { - g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u kbps", 64 + (value - 0x40) * 8); - return result; - } - if ((value >= 0x80) && (value <= 0xfe)) { - g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u kbps", 576 + (value - 0x80) * 64); - return result; - } - return "0 kbps"; -} - -static const char* -translate_abqp_max_bit_rate_for_dl(guint8 value, build_info_t *bi) { - return translate_abqp_max_bit_rate_for_ul(value, bi); -} - -static const char* -translate_abqp_residual_ber(guint8 value, build_info_t *bi) { - switch (value) { - case 0: - if (bi->ul_data) { - return "Subscribed residual BER"; - } - else { - return "Reserved"; - } - case 1: return "5*10^-2"; - case 2: return "1*10^-2"; - case 3: return "5*10^-3"; - case 4: return "4*10^-3"; - case 5: return "1*10^-3"; - case 6: return "1*10^-4"; - case 7: return "1*10^-5"; - case 8: return "1*10^-6"; - case 9: return "6*10^-8"; - case 15: return "Reserved"; - } - if (bi->ul_data) { - /* The MS shall consider all other values as reserved */ - return "Reserved"; - } - else { - /* The network shall map all other values not explicitly defined onto one of the values defined in this version of the protocol. The network shall return a negotiated value which is explicitly defined in this version of the protocol */ - return "Error"; - } -} - -static const char* -translate_abqp_sdu_error_ratio(guint8 value, build_info_t *bi) { - switch (value) { - case 0: - if (bi->ul_data) { - return "Subscribed SDU error ratio"; - } - else { - return "Reserved"; - } - case 1: return "1*10^-2"; - case 2: return "7*10^-3"; - case 3: return "1*10^-3"; - case 4: return "1*10^-4"; - case 5: return "1*10^-5"; - case 6: return "1*10^-6"; - case 7: return "1*10^-1"; - case 15: return "Reserved"; - } - if (bi->ul_data) { - /* The MS shall consider all other values as reserved */ - return "Reserved"; - } - else { - /* The network shall map all other values not explicitly defined onto one of the values defined in this version of the protocol. The network shall return a negotiated value which is explicitly defined in this version of the protocol */ - return ""; - } -} - -static const char* -translate_abqp_transfer_delay(guint8 value, build_info_t *bi) { - static char result[BSSGP_TRANSLATION_MAX_LEN]; - - if (value == 0) { - if (bi->ul_data) { - return "Subscribed transfer delay"; - } - else { - return "Reserved"; - } - } - if ((value >= 1) && (value <= 0x0f)) { - g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u ms", value * 10); - return result; - } - if ((value >= 0x10) && (value <= 0x1f)) { - g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u ms", 200 + (value - 0x10) * 50); - return result; - } - if ((value >= 0x20) && (value <= 0x3e)) { - g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u ms", 1000 + (value - 0x20) * 100); - return result; - } - return "Reserved"; -} - -static const char* -translate_abqp_traffic_handling_priority(guint8 value, build_info_t *bi) { - switch (value) { - case 0: - if (bi->ul_data) { - return "Subscribed traffic handling_priority"; - } - else { - return "Reserved"; - } - case 1: return "Priority level 1"; - case 2: return "Priority level 2"; - case 3: return "Priority level 3"; - default: return ""; - } -} - -static const char* -translate_abqp_guaranteed_bit_rate_for_ul(guint8 value, build_info_t *bi) { - return translate_abqp_max_bit_rate_for_ul(value, bi); -} -static const char* -translate_abqp_guaranteed_bit_rate_for_dl(guint8 value, build_info_t *bi) { - return translate_abqp_max_bit_rate_for_ul(value, bi); -} - -static const char* -translate_abqp_source_statistics_descriptor(guint8 value, build_info_t *bi) { - if (bi->ul_data) { - switch (value) { - case 0: return "Unknown"; - case 1: return "Speech"; - default: return "Unknown"; - } - } - else { - return "Spare"; - } -} - -static const char* -translate_abqp_max_bit_rate_for_dl_extended(guint8 value, build_info_t *bi _U_) { - static char result[BSSGP_TRANSLATION_MAX_LEN]; - - if (value == 0) { - return "Use the value indicated by the Maximum bit rate for downlink"; - } - if ((value >= 1) && (value <= 0x4a)) { - g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u kbps", 8600 + value * 100); - return result; - } - /* The network shall map all other values not explicitly defined onto one of the values defined in this version of the protocol. The network shall return a negotiated value which is explicitly defined in this version of the protocol */ - return ""; -} - -static const char* -translate_abqp_guaranteed_bit_rate_for_dl_extended(guint8 value, build_info_t *bi _U_) { - static char result[BSSGP_TRANSLATION_MAX_LEN]; - - if (value == 0) { - return "Use the value indicated by the Guaranteed bit rate for downlink"; - } - if ((value >= 1) && (value <= 0x4a)) { - g_snprintf(result, BSSGP_TRANSLATION_MAX_LEN, "%u kbps", 8600 + value * 100); - return result; - } - /* The network shall map all other values not explicitly defined onto one of the values defined in this version of the protocol. The network shall return a negotiated value which is explicitly defined in this version of the protocol */ - return ""; -} - -static const char* -translate_msrac_access_technology_type(guint8 value) { - static const value_string tab_values[] = { - { 0, "GSM P" }, - { 1, "GSM E" }, - { 2, "GSM R" }, - { 3, "GSM 1800" }, - { 4, "GSM 1900" }, - { 5, "GSM 450" }, - { 6, "GSM 480" }, - { 7, "GSM 850" }, - { 8, "GSM 700" }, - { 9, "GSM T 380" }, - { 10, "GSM T 410" }, - { 11, "GSM T 900" }, - { 15, "List of Additional Access Technologies present" }, - { 0, NULL }, - /* Otherwise "Unknown" */ - }; - return val_to_str(value, tab_values, "Unknown"); -} - -static const char* -translate_msrac_dtm_gprs_multislot_class(guint8 value) { - static const value_string tab_values[] = { - { 0, "Unused, interpreted as \"Multislot class 5 supported\"" }, - { 1, "Multislot class 5 supported" }, - { 2, "Multislot class 9 supported" }, - { 3, "Multislot class 11 supported" }, - { 0, NULL }, - /* No other combinations*/ - }; - return val_to_str(value, tab_values, ""); -} - -static const char* -translate_msrac_extended_dtm_gprs_multislot_class(guint8 value, guint8 dgmsc) { - switch (dgmsc) { - case 0: return "Unused, interpreted as Multislot class 5 supported"; - case 1: - switch (value) { - case 0: return "Multislot class 5 supported"; - case 1: return "Multislot class 6 supported"; - case 2: - case 3: - return "Unused, interpreted as Multislot class 5 supported"; - } - case 2: - switch (value) { - case 0: return "Multislot class 9 supported"; - case 1: return "Multislot class 10 supported"; - case 2: - case 3: - return "Unused, interpreted as Multislot class 5 supported"; - } - case 3: - switch (value) { - case 0: return "Multislot class 11 supported"; - case 1: - case 2: - case 3: - return "Unused, interpreted as Multislot class 5 supported"; - } - } - DISSECTOR_ASSERT_NOT_REACHED(); - return "Error"; /* Dummy */ -} - -#if 0 -static guint8 -translate_msrac_high_multislot_capability(guint8 capability, guint8 class) { - switch (capability) { - case 0: - switch (class) { - case 8: - return 30; - case 10: - case 23: - case 28: - case 29: - return 39; - case 11: - case 20: - case 25: - return 32; - case 12: - case 21: - case 22: - case 26: - case 27: - return 33; - default: - return class; - } - case 1: - switch (class) { - case 8: - return 35; - case 10: - case 19: - case 24: - return 36; - case 11: - case 23: - case 28: - case 29: - return 45; - case 12: - case 21: - case 22: - case 26: - case 27: - return 38; - default: - return class; - } - case 2: - switch (class) { - case 8: - return 40; - case 10: - case 19: - case 24: - return 41; - case 11: - case 20: - case 25: - return 42; - case 12: - case 23: - case 28: - case 29: - return 44; - default: - return class; - } - case 3: - switch (class) { - case 12: - case 21: - case 22: - case 26: - case 27: - return 43; - case 11: - case 20: - case 25: - return 37; - case 10: - case 19: - case 24: - return 31; - case 9: - case 23: - case 28: - case 29: - return 34; - default: - return class; - } - } - DISSECTOR_ASSERT_NOT_REACHED(); - return 0; -} -#endif - -static const char* -translate_channel_needed(guint8 value) { - switch (value) { - case 0: return "Any channel"; - case 1: return "SDCCH"; - case 2: return "TCH/F (Full rate)"; - case 3: return "TCH/H or TCH/F (Dual rate)"; - } - DISSECTOR_ASSERT_NOT_REACHED(); - return NULL; -} - -static proto_item* -bssgp_proto_tree_add_ie(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const char *iename; - - iename = ie->name; - if (iename == NULL) - iename = val_to_str(ie->iei, tab_bssgp_ie_types, "Unknown"); - return proto_tree_add_uint_format(bi->bssgp_tree, hf_bssgp_ie_type, - bi->tvb, ie_start_offset, 1, - ie->iei, "%s", iename); -} - -static void -bssgp_proto_handoff(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset, dissector_handle_t handle) { - tvbuff_t *next_tvb=NULL; - - if(ie->value_length > 0) - next_tvb = tvb_new_subset_remaining(bi->tvb, bi->offset); - - if (bi->bssgp_tree) { - bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - } - if(next_tvb){ - if (handle) { - call_dissector(handle, next_tvb, bi->pinfo, bi->parent_tree); - } - else if (data_handle) { - call_dissector(data_handle, next_tvb, bi->pinfo, bi->parent_tree); - } - } -} - -static void -decode_nri(proto_tree *tf, build_info_t *bi, guint32 tmsi_tlli) { - proto_item *hidden_item; - const guint32 LOCAL_TLLI_MASK = 0xc0000000; - const guint32 FOREIGN_TLLI_MASK = 0x80000000; - guint16 nri; - - if (bssgp_decode_nri && (bssgp_nri_length != 0) && - (((tmsi_tlli & LOCAL_TLLI_MASK) == LOCAL_TLLI_MASK) || - ((tmsi_tlli & FOREIGN_TLLI_MASK) == FOREIGN_TLLI_MASK))) { - nri = get_masked_guint32(tmsi_tlli, make_mask32( (guint8) bssgp_nri_length, 8)); - if (tf) { - hidden_item = proto_tree_add_uint(tf, hf_bssgp_nri, bi->tvb, bi->offset, 4, nri); - PROTO_ITEM_SET_HIDDEN(hidden_item); - } - col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP, "NRI %u", nri); - } -} - -static void -decode_mobile_identity(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { -#define MAX_NUM_IMSI_DIGITS 15 - const guint8 MASK_ODD_EVEN_INDICATION = 0x08; - const guint8 MASK_TYPE_OF_IDENTITY = 0x07; - const guint8 ODD = 1; - proto_item *ti = NULL, *pi; - proto_tree *tf = NULL; - guint8 data, odd_even, type, num_digits, i; - int hf_id; - guint32 tmsi; - guint8 digits[MAX_NUM_IMSI_DIGITS]; - char digits_str[MAX_NUM_IMSI_DIGITS + 1]; - - static const value_string tab_type_of_identity[] = { - { BSSGP_MOBILE_IDENTITY_TYPE_IMSI, "IMSI" }, - { BSSGP_MOBILE_IDENTITY_TYPE_IMEI, "IMEI" }, - { BSSGP_MOBILE_IDENTITY_TYPE_IMEISV, "IMEISV" }, - { BSSGP_MOBILE_IDENTITY_TYPE_TMSI_PTMSI, "TMSI//P-TMSI" }, - { BSSGP_MOBILE_IDENTITY_TYPE_NO_IDENTITY, "No identity" }, - { 0, NULL }, - /* Otherwise "Reserved" */ - }; - - digits_str[0] = '\0'; /* conceivably num_digits below could be zero */ - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_mobile_identity); - } - data = tvb_get_guint8(bi->tvb, bi->offset); - odd_even = get_masked_guint8(data, MASK_ODD_EVEN_INDICATION); - - if (bi->bssgp_tree) { - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, - MASK_ODD_EVEN_INDICATION); - proto_item_append_text(pi, "Odd/Even Indication: %s number of identity digits%s", - odd_even == ODD ? "Odd" : "Even", - odd_even == ODD ? "" : " and also when the TMSI/P_TMSI is used"); - } - type = get_masked_guint8(data, MASK_TYPE_OF_IDENTITY); - - if (bi->bssgp_tree) { - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, - MASK_TYPE_OF_IDENTITY); - proto_item_append_text(pi, "Type of Identity: %s", - val_to_str(type, tab_type_of_identity, - "Reserved")); - } - bi->offset++; - switch (type) { - case BSSGP_MOBILE_IDENTITY_TYPE_IMSI: - case BSSGP_MOBILE_IDENTITY_TYPE_IMEI: - case BSSGP_MOBILE_IDENTITY_TYPE_IMEISV: - num_digits = 1 + (ie->value_length - 1) * 2; - if (odd_even != ODD ) num_digits--; - if (num_digits > MAX_NUM_IMSI_DIGITS) THROW(ReportedBoundsError); - - i = 0; - digits[i] = get_masked_guint8(data, BSSGP_MASK_LEFT_OCTET_HALF); - - i++; - while (TRUE) { - data = tvb_get_guint8(bi->tvb, bi->offset); - - digits[i] = get_masked_guint8(data, BSSGP_MASK_RIGHT_OCTET_HALF); - i++; - if (i >= num_digits) break; - - digits[i] = get_masked_guint8(data, BSSGP_MASK_LEFT_OCTET_HALF); - i++; - if (i >= num_digits) break; - bi->offset++; - } - bi->offset++; - - if (bi->bssgp_tree) { - proto_item_append_text(ti, ": "); - for (i = 0; i < num_digits; i++) { - proto_item_append_text(ti, "%u", digits[i]); - g_snprintf(&digits_str[i], 2, "%u", digits[i]); - } - switch (type) { - case BSSGP_MOBILE_IDENTITY_TYPE_IMSI: - hf_id = hf_bssgp_imsi; - break; - case BSSGP_MOBILE_IDENTITY_TYPE_IMEI: - hf_id = hf_bssgp_imei; - break; - case BSSGP_MOBILE_IDENTITY_TYPE_IMEISV: - hf_id = hf_bssgp_imeisv; - break; - default: - DISSECTOR_ASSERT_NOT_REACHED(); - hf_id = -1; - break; - } - if (tf) - proto_tree_add_string(tf, hf_id, bi->tvb, ie_start_offset + 2, ((num_digits/2)+1), digits_str); - - } - col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP, "%s %s", - val_to_str(type, tab_type_of_identity, - "Mobile identity unknown"), - digits_str); - break; - case BSSGP_MOBILE_IDENTITY_TYPE_TMSI_PTMSI: - tmsi = tvb_get_ntohl(bi->tvb, bi->offset); - col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP, - "TMSI/P-TMSI %0x04x", tmsi); - if (bi->bssgp_tree) { - proto_tree_add_item(tf, hf_bssgp_tmsi_ptmsi, bi->tvb, bi->offset, 4, - ENC_BIG_ENDIAN); - proto_item_append_text(ti, ": %#04x", tmsi); - } - decode_nri(tf, bi, tmsi); - bi->offset += 4; - break; - default: - ; - } -#undef MAX_NUM_IMSI_DIGITS -} - -static char* -decode_mcc_mnc(build_info_t *bi, proto_tree *parent_tree) { -#define RES_LEN 15 - const guint8 UNUSED_MNC3 = 0x0f; - guint8 mcc1, mcc2, mcc3, mnc1, mnc2, mnc3, data; - guint16 start_offset, mcc, mnc; - static char mcc_mnc[RES_LEN]; - - start_offset = bi->offset; - - - data = tvb_get_guint8(bi->tvb, bi->offset); - mcc2 = get_masked_guint8(data, BSSGP_MASK_LEFT_OCTET_HALF); - mcc1 = get_masked_guint8(data, BSSGP_MASK_RIGHT_OCTET_HALF); - bi->offset++; - - data = tvb_get_guint8(bi->tvb, bi->offset); - mnc3 = get_masked_guint8(data, BSSGP_MASK_LEFT_OCTET_HALF); - mcc3 = get_masked_guint8(data, BSSGP_MASK_RIGHT_OCTET_HALF); - bi->offset++; - - data = tvb_get_guint8(bi->tvb, bi->offset); - mnc2 = get_masked_guint8(data, BSSGP_MASK_LEFT_OCTET_HALF); - mnc1 = get_masked_guint8(data, BSSGP_MASK_RIGHT_OCTET_HALF); - bi->offset++; - - /* XXX: If mxci out of range the ms should transmit the values using full hexademical encoding? */ - - /* XXX: Interpretation of mcci? */ - mcc = 100 * mcc1 + 10 * mcc2 + mcc3; - - /* XXX: Interpretation of mnci? */ - mnc = 10 * mnc1 + mnc2; - - if (mnc3 != UNUSED_MNC3) { - mnc += 10 * mnc + mnc3; - } - - proto_tree_add_uint(parent_tree, hf_bssgp_mcc, - bi->tvb, start_offset, 3, mcc); - proto_tree_add_uint(parent_tree, hf_bssgp_mnc, - bi->tvb, start_offset, 3, mnc); - - if (mnc3 != UNUSED_MNC3) { - /* Three digits mnc */ - g_snprintf(mcc_mnc, RES_LEN, "%u-%03u", mcc, mnc); - } - else { - /* Two digits mnc */ - g_snprintf(mcc_mnc, RES_LEN, "%u-%02u", mcc, mnc); - } -#undef RES_LEN - return mcc_mnc; -} - -static char* -decode_lai(build_info_t *bi, proto_tree *parent_tree) { -#define RES_LEN 15 - guint16 lac; - char *mcc_mnc; - static char lai[RES_LEN]; - - mcc_mnc = decode_mcc_mnc(bi, parent_tree); - - lac = tvb_get_ntohs(bi->tvb, bi->offset); - proto_tree_add_item(parent_tree, hf_bssgp_lac, - bi->tvb, bi->offset, 2, ENC_BIG_ENDIAN); - bi->offset += 2; - - g_snprintf(lai, RES_LEN, "%s-%u", mcc_mnc, lac); -#undef RES_LEN - return lai; -} - -static char* -decode_rai(build_info_t *bi, proto_tree *parent_tree) { -#define RES_LEN 20 - guint8 rac; - static char rai[RES_LEN]; - char *lai = decode_lai(bi, parent_tree); - - rac = tvb_get_guint8(bi->tvb, bi->offset); - proto_tree_add_item(parent_tree, hf_bssgp_rac, bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN); - bi->offset++; - - g_snprintf(rai, RES_LEN, "%s-%u", lai, rac); -#undef RES_LEN - return rai; -} - -static char* -decode_rai_ci(build_info_t *bi, proto_tree *parent_tree) { -#define RES_LEN 30 - char *rai; - static char rai_ci[RES_LEN]; - guint16 ci; - - rai = decode_rai(bi, parent_tree); - - ci = tvb_get_ntohs(bi->tvb, bi->offset); - proto_tree_add_item(parent_tree, hf_bssgp_ci, - bi->tvb, bi->offset, 2, ENC_BIG_ENDIAN); - bi->offset += 2; - g_snprintf(rai_ci, RES_LEN, "RAI %s, CI %u", rai, ci); -#undef RES_LEN - return rai_ci; -} - -static void -bssgp_pi_append_queuing_delay(proto_item *pi, tvbuff_t *tvb, int offset) { - const guint16 INFINITE_DELAY = 0xffff; - guint16 value = tvb_get_ntohs(tvb, offset); - if (value == INFINITE_DELAY) { - proto_item_append_text(pi, ": Infinite delay (%#4x)", value); - } - else { - proto_item_append_text(pi, ": %u centi-seconds delay", value); - } -} - -static void -bssgp_pi_append_bucket_leak_rate(proto_item *pi, tvbuff_t *tvb, int offset) { - guint16 value = tvb_get_ntohs(tvb, offset); - proto_item_append_text(pi, ": %u bits", value * 100); -} - -static void -bssgp_pi_append_bucket_size(proto_item *pi, tvbuff_t *tvb, int offset) { - guint16 value = tvb_get_ntohs(tvb, offset); - proto_item_append_text(pi, ": %u bytes", value * 100); -} - -static void -bssgp_pi_append_bucket_full_ratio(proto_item *pi, tvbuff_t *tvb, int offset) { - guint8 value = tvb_get_guint8(tvb, offset); - proto_item_append_text(pi, ": %.2f * Bmax ", value / 100.0); -} - -static void -bssgp_pi_append_pfi(proto_item *pi, tvbuff_t *tvb, int offset) { - const guint8 MASK_PFI = 0x7f; - guint8 value; - - static const value_string tab_pfi[] = { - { 0, "Best effort" }, - { 1, "Signaling" }, - { 2, "SMS" }, - { 3, "TOMB" }, - { 4, "Reserved" }, - { 5, "Reserved" }, - { 6, "Reserved" }, - { 7, "Reserved" }, - { 0, NULL }, - /* Otherwise "Dynamically assigned (PFI: <value>)" */ - }; - value = tvb_get_masked_guint8(tvb, offset, MASK_PFI); - proto_item_append_text(pi, - "%s", val_to_str(value, tab_pfi, "Dynamically assigned (PFI: %d)")); -} - -static void -decode_pfi(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - bssgp_pi_append_pfi(ti, bi->tvb, bi->offset); - } - bi->offset += ie->value_length; -} - -static void -decode_queuing_delay(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - bssgp_pi_append_queuing_delay(ti, bi->tvb, bi->offset); - } - bi->offset += ie->value_length; -} - -static void -decode_bucket_size(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - bssgp_pi_append_bucket_size(ti, bi->tvb, bi->offset); - } - bi->offset += ie->value_length; -} - -static void -decode_bucket_leak_rate(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - bssgp_pi_append_bucket_leak_rate(ti, bi->tvb, bi->offset); - } - bi->offset += ie->value_length; -} - -static void -get_value_length(bssgp_ie_t *ie, build_info_t *bi) { - /* length indicator in bit 8, 0 => two bytes, 1 => one byte */ - const guint8 MASK_LENGTH_INDICATOR = 0x80; - const guint8 MASK_ONE_BYTE_LENGTH = 0x7f; - guint8 length_len; - guint16 length; - - length = tvb_get_guint8(bi->tvb, bi->offset); - length_len = 1; - - if (length & MASK_LENGTH_INDICATOR) { - length &= MASK_ONE_BYTE_LENGTH; - } - else { - length_len++; - length <<= 8; - length |= tvb_get_guint8(bi->tvb, bi->offset+1); - } - ie->value_length = length; - ie->total_length += length_len + length; - bi->offset += length_len; -} - -static void -decode_simple_ie(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset, - const char *pre_str, const char *post_str, - gboolean show_as_dec) { - /* XXX: Allow mask? */ - proto_item *ti; - guint32 value; - - switch (ie->value_length) { - case 1: value = tvb_get_guint8(bi->tvb, bi->offset); break; - case 2: value = tvb_get_ntohs(bi->tvb, bi->offset); break; - case 3: value = tvb_get_ntoh24(bi->tvb, bi->offset); break; - case 4: value = tvb_get_ntohl(bi->tvb, bi->offset); break; - default: value = 0; break; - } - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - - proto_item_append_text(ti, ": "); - - if (pre_str) { - proto_item_append_text(ti, "%s ", pre_str); - } - if (show_as_dec) { - proto_item_append_text(ti, "%u", value); - } - else { - switch (ie->value_length) { - case 1: proto_item_append_text(ti, "%#1x", value); break; - case 2: proto_item_append_text(ti, "%#2x", value); break; - case 3: proto_item_append_text(ti, "%#3x", value); break; - case 4: proto_item_append_text(ti, "%#4x", value); break; - default: ; - } - } - proto_item_append_text(ti, " %s", post_str); - } - bi->offset += ie->value_length; -} - -static int -check_correct_iei(bssgp_ie_t *ie, build_info_t *bi) { - guint8 fetched_iei = tvb_get_guint8(bi->tvb, bi->offset); - -#ifdef BSSGP_DEBUG - if (fetched_iei != ie->iei) { - proto_tree_add_text(bi->bssgp_tree, bi->tvb, bi->offset, 1, - "Tried IEI %s (%#02x), found IEI %s (%#02x)", - val_to_str(ie->iei, tab_bssgp_ie_types, "Unknown"), - ie->iei, - val_to_str(fetched_iei, tab_bssgp_ie_types, "Unknown"), - fetched_iei); - } -#endif - return (fetched_iei == ie->iei); -} - -static void -decode_iei_alignment_octets(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - proto_item_append_text(ti, " (%u bytes)", ie->value_length); - } - bi->offset += ie->value_length; -} - -static void -decode_iei_bvci(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti, *hidden_item; - guint16 bvci; - - bvci = tvb_get_ntohs(bi->tvb, bi->offset); - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - proto_item_append_text(ti, ": %u", bvci); - hidden_item = proto_tree_add_item(bi->bssgp_tree, hf_bssgp_bvci, - bi->tvb, bi->offset, 2, - ENC_BIG_ENDIAN); - PROTO_ITEM_SET_HIDDEN(hidden_item); - } - bi->offset += ie->value_length; - - col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP, - "BVCI %u", bvci); -} - -static const value_string tab_cause[] = { - { 0x00, "Processor overload" }, - { 0x01, "Equipment failure" }, - { 0x02, "Transit network service failure" }, - { 0x03, "Network service transmission capacity modified from zero kbps to greater than zero kbps" }, - { 0x04, "Unknown MS" }, - { 0x05, "BVCI unknown" }, - { 0x06, "Cell traffic congestion" }, - { 0x07, "SGSN congestion" }, - { 0x08, "O&M intervention" }, - { 0x09, "BVCI blocked" }, - { 0x0a, "PFC create failure" }, - { 0x0b, "PFC preempted" }, - { 0x0c, "ABQP no more supported" }, - { 0x20, "Semantically incorrect PDU" }, - { 0x21, "Invalid mandatory information" }, - { 0x22, "Missing mandatory IE" }, - { 0x23, "Missing conditional IE" }, - { 0x24, "Unexpected conditional IE" }, - { 0x25, "Conditional IE error" }, - { 0x26, "PDU not compatible with the protocol state" }, - { 0x27, "Protocol error - unspecified" }, - { 0x28, "PDU not compatible with the feature set" }, - { 0x29, "Requested information not available" }, - { 0x2a, "Unknown destination address" }, - { 0x2b, "Unknown RIM application identity" }, - { 0x2c, "Invalid container unit information" }, - { 0x2d, "PFC queuing" }, - { 0x2e, "PFC created successfully" }, - { 0x2f, "T12 expiry" }, - { 0x30, "MS under PS Handover treatment" }, - { 0x31, "Uplink quality" }, - { 0x32, "Uplink strength" }, - { 0x33, "Downlink quality" }, - { 0x34, "Downlink strength" }, - { 0x35, "Distance" }, - { 0x36, "Better cell" }, - { 0x37, "Traffic" }, - { 0x38, "Radio contact lost with MS" }, - { 0x39, "MS back on old channel" }, - { 0x3a, "T13 expiry" }, - { 0x3b, "T14 expiry" }, - { 0x3c, "Not all requested PFCs created" }, - { 0x3d, "CS cause" }, - { 0x3e, "Requested ciphering and/or integrity protection algorithms not supported" }, - { 0x3f, "Relocation failure in target system" }, - { 0x40, "Directed Retry" }, - { 0x41, "Time critical relocation" }, - { 0x42, "PS Handover Target not allowed" }, - { 0x43, "PS Handover not Supported in Target BSS or Target System" }, - { 0x44, "Incoming relocation not supported due to PUESBINE feature" }, - { 0, NULL }, -}; -/* - * 11.3.8 Cause - */ -static void -decode_iei_cause(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - guint8 value; - - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - value = tvb_get_guint8(bi->tvb, bi->offset); - proto_item_append_text(ti, ": %s (%#02x)", - val_to_str(value, tab_cause, - "Protocol error - unspecified"), - value); - } - bi->offset += ie->value_length; -} - -/* - * 11.3.9 Cell Identifier 3GPP TS 48.018 version 6.7.0 Release 6 - */ -static void -decode_iei_cell_identifier(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - proto_tree *tf; - char *rai_ci; - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_cell_identifier); - - rai_ci = decode_rai_ci(bi, tf); - proto_item_append_text(ti, ": %s", rai_ci); - - } else { - bi->offset += ie->value_length; - } - -} - -/* - * 11.3.10 Channel needed - */ -static void -decode_iei_channel_needed(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - /* XXX: 'If this IE is used for only one MS, the the first CHANNEL field - is used and the second CHANNEL field is spare.' How know? */ - const guint8 MASK_CH1 = 0x03; - const guint8 MASK_CH2 = 0x0c; - proto_item *ti; - guint8 data, ch1, ch2; - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - data = tvb_get_guint8(bi->tvb, bi->offset); - ch1 = get_masked_guint8(data, MASK_CH1); - ch2 = get_masked_guint8(data, MASK_CH2); - proto_item_append_text(ti, ": Ch1: %s (%u), Ch2: %s (%u)", - translate_channel_needed(ch1), - ch1, - translate_channel_needed(ch2), - ch2); - } - bi->offset += ie->value_length; -} -/* - * 11.3.11 DRX Parameters - */ -static void -decode_iei_drx_parameters(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 MASK_CYCLE_LENGTH_COEFFICIENT = 0xf0; - const guint8 MASK_SPLIT_ON_CCCH = 0x08; - const guint8 MASK_NON_DRX_TIMER = 0x07; - proto_item *ti, *pi; - proto_tree *tf; - guint8 data, value; - guint16 cycle_value; - - static const value_string tab_non_drx_timer[] = { - { 0, "No non-DRX mode after transfer state" }, - { 1, "Max. 1 sec non-DRX mode after transfer state" }, - { 2, "Max. 2 sec non-DRX mode after transfer state" }, - { 3, "Max. 4 sec non-DRX mode after transfer state" }, - { 4, "Max. 8 sec non-DRX mode after transfer state" }, - { 5, "Max. 16 sec non-DRX mode after transfer state" }, - { 6, "Max. 32 sec non-DRX mode after transfer state" }, - { 7, "Max. 64 sec non-DRX mode after transfer state" }, - { 0, NULL}, - /* Otherwise "" */ - }; - - static const value_string tab_cycle_length_coefficient[] = { - { 0, "CN Specific DRX cycle length coefficient not specified by the MS, ie. the system information value 'CN domain specific DRX cycle length' is used" }, - { 6, "CN Specific DRX cycle length coefficient 6" }, - { 7, "CN Specific DRX cycle length coefficient 7" }, - { 8, "CN Specific DRX cycle length coefficient 8" }, - { 9, "CN Specific DRX cycle length coefficient 9" }, - { 0, NULL }, - /* Otherwise "CN Specific DRX cycle length coefficient not specified by the MS" */ - }; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_drx_parameters); - - value = tvb_get_guint8(bi->tvb, bi->offset); - proto_tree_add_text(tf, bi->tvb, bi->offset, 1, - "SPLIT PG CYCLE: code %u", value); - if ((value >= 1) && (value <= 64)) { - cycle_value = value; - } - else { - switch (value) { - case 0: cycle_value = 704; break; - case 65: cycle_value = 71; break; - case 66: cycle_value = 72; break; - case 67: cycle_value = 74; break; - case 68: cycle_value = 75; break; - case 69: cycle_value = 77; break; - case 70: cycle_value = 79; break; - case 71: cycle_value = 80; break; - case 72: cycle_value = 83; break; - case 73: cycle_value = 86; break; - case 74: cycle_value = 88; break; - case 75: cycle_value = 90; break; - case 76: cycle_value = 92; break; - case 77: cycle_value = 96; break; - case 78: cycle_value = 101; break; - case 79: cycle_value = 103; break; - case 80: cycle_value = 107; break; - case 81: cycle_value = 112; break; - case 82: cycle_value = 116; break; - case 83: cycle_value = 118; break; - case 84: cycle_value = 128; break; - case 85: cycle_value = 141; break; - case 86: cycle_value = 144; break; - case 87: cycle_value = 150; break; - case 88: cycle_value = 160; break; - case 89: cycle_value = 171; break; - case 90: cycle_value = 176; break; - case 91: cycle_value = 192; break; - case 92: cycle_value = 214; break; - case 93: cycle_value = 224; break; - case 94: cycle_value = 235; break; - case 95: cycle_value = 256; break; - case 96: cycle_value = 288; break; - case 97: cycle_value = 320; break; - case 98: cycle_value = 352; break; - default: - cycle_value = 1; - } - proto_item_append_text(ti, " => value %u", cycle_value); - if (cycle_value == 704) { - proto_item_append_text(ti, " (equivalent to no DRX)"); - } - } - bi->offset++; - - data = tvb_get_guint8(bi->tvb, bi->offset); - - value = get_masked_guint8(data, MASK_CYCLE_LENGTH_COEFFICIENT); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, - MASK_CYCLE_LENGTH_COEFFICIENT); - proto_item_append_text(pi, "CN specific DRX cycle length coefficient: %s (%#02x)", - val_to_str(value, tab_cycle_length_coefficient, - "Not specified by the MS"), - value); - - value = get_masked_guint8(data, MASK_SPLIT_ON_CCCH); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_SPLIT_ON_CCCH); - proto_item_append_text(pi, "SPLIT on CCCH: Split pg cycle on CCCH is%s supported by the mobile station", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_NON_DRX_TIMER); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_NON_DRX_TIMER); - proto_item_append_text(pi, "Non-DRX Timer: %s (%#x)", - val_to_str(value, tab_non_drx_timer, ""), value); - bi->offset++; -} - -/* - * 11.3.12 eMLPP-Priority - */ - -static void -decode_iei_emlpp_priority(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 MASK_CALL_PRIORITY = 0x07; - proto_item *ti; - guint8 data, value; - - static const value_string tab_call_priority[] = { - { 0, "No priority applied" }, - { 1, "Call priority level 4" }, - { 2, "Call priority level 3" }, - { 3, "Call priority level 2" }, - { 4, "Call priority level 1" }, - { 5, "Call priority level 0" }, - { 6, "Call priority level B" }, - { 7, "Call priority level A" }, - { 0, NULL }, - }; - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - data = tvb_get_guint8(bi->tvb, bi->offset); - value = get_masked_guint8(data, MASK_CALL_PRIORITY); - proto_item_append_text(ti, ": %s", - val_to_str(value, tab_call_priority, "")); - } - bi->offset += ie->value_length; -} -/* - * 11.3.13 Flush Action - */ - -static void -decode_iei_flush_action(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - guint8 value; - - static const value_string tab_action_value[] = { - { 0x00, "LLC-PDU(s) deleted" }, - { 0x01, "LLC-PDU(s) transferred" }, - { 0, NULL }, - /* Otherwise "Reserved" */ - }; - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - value = tvb_get_guint8(bi->tvb, bi->offset); - proto_item_append_text(ti, ": %s (%u)", - val_to_str(value, tab_action_value, "Reserved"), - value); - - } - bi->offset += ie->value_length; -} -/* - * 11.3.16 LLC Frames Discarded - */ - -static void -decode_iei_llc_frames_discarded(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - decode_simple_ie(ie, bi, ie_start_offset, "", " frames discarded", TRUE); -} -/* - * 11.3.17 Location Area - */ -static void -decode_iei_location_area(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - proto_tree *tf; - char *lai; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_location_area); - - lai = decode_rai(bi, tf); - proto_item_append_text(ti, ": LAI %s", lai); -} - -static void -decode_msrac_additional_access_technologies(proto_tree *tree, tvbuff_t *tvb, - guint32 bo, guint32 length _U_) { - proto_item *pi; - guint8 value; - guint8 bl; /* Bit length */ - - bl = 4; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "Access Technology Type: %s (%#01x)", - translate_msrac_access_technology_type(value), - value); - - bl = 3; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "GMSK Power Class: Power class %u", value); - - bl = 2; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "8PSK Power Class"); - if (value == 0) { - proto_item_append_text(pi, ": 8PSK modulation not supported for uplink"); - } - else{ - proto_item_append_text(pi, ": Power Class E%u", value); - } -} - -static gboolean -struct_bits_exist(guint32 start_bo, guint32 struct_length, - guint32 bo, guint32 num_bits) { - return (bo + num_bits) <= (start_bo + struct_length); - -} - -static void -decode_msrac_access_capabilities(proto_tree *tree, tvbuff_t *tvb, - guint32 bo, guint32 struct_length) { - /* Error handling: - - Struct too short: assume features do not exist - - Struct too long: ignore data and jump to next Access Technology */ - proto_item *ti, *pi; - proto_tree *tf; - guint8 value, i; - guint8 dgmsc = 0, demsc = 0; /* DTM GPRS/EGPRS Multi Slot Class */ - guint8 bl; /* Bit length */ - guint32 start_bo = bo; - - /* RF Power Capability */ - bl = 3; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "RF Power Capability"); - if (value == 0) { - proto_item_append_text(pi, ": The MS does not support any GSM access technology type"); - } - else { - proto_item_append_text(pi, ": GMSK Power Class %u", value); - } - - /* A5 bits */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - if (value == 1) { - bo += bl; - bl = 7; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - ti = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - proto_item_append_text(ti, "A5 Bits: %#02x", value); - tf = proto_item_add_subtree(ti, ett_bssgp_msrac_a5_bits); - for (i = 0; i < bl; i++) { - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo + i, 1); - proto_item_append_text(pi, "Encryption algorithm A5/%u%s available", - i + 1, - value & (0x40 >> i) ? "" : " not"); - } - bo += bl; - } - else { - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "A5 bits: Same as in the immediately preceding Access capabilities field within this IE"); - } - - /* ES IND */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "ESD IND: Controlled Early Classmark Sending"" option is%s implemented", - value == 0 ? " not" : ""); - - /* PS */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "PS: PS capability%s present", - value == 0 ? " not" : ""); - - /* VGCS */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "VBCS:%s VGCS capability %s notifications wanted", - value == 0 ? " No" : "", - value == 0 ? "or no" : "and"); - - /* VBS */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "VBS:%s VBS capability %s notifications wanted", - value == 0 ? " No" : "", - value == 0 ? "or no" : "and"); - - /* Multislot capability */ - /* XXX: 'Error: struct too short, assume features do not exist' - No length is given! */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - if (value == 1) { - bo += bl; - ti = bit_proto_tree_add_text(tree, tvb, bo, bl, "Multislot capability"); - tf = proto_item_add_subtree(ti, ett_bssgp_msrac_multislot_capability); - - /* HSCSD Multislot Class */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - bo += bl; - if (value == 1) { - bl = 5; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "HSCSD Multislot Class"); - if ((value > 0 ) && (value < 19)) { - proto_item_append_text(pi, ": Multislot Class %u", value); - } - else { - proto_item_append_text(pi, ": Reserved"); - } - } - else - { - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo-1, bl); - proto_item_append_text(pi, "HSCSD Multislot Class - Bits are not available" ); - } - - /* GPRS Multislot Class, GPRS Extended Dynamic Allocation Capability */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - bo += bl; - if (value == 1) { - bl = 5; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "GPRS Multislot Class: Multislot Class %u", - value); - - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "GPRS Extended Dynamic Allocation Capability: Extended Dynamic Allocation for GPRS is%s implemented", - value == 0 ? " not" : ""); - } - else - { - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo-1, bl); - proto_item_append_text(pi, "GPRS Multislot Class: Multislot Class - Bits are not available" ); - } - - /* SMS Value, SM Value */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - bo += bl; - if (value == 1) { - bl = 4; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, - "SMS_VALUE: %u/4 timeslot (~%u microseconds)", - value + 1, (value + 1) * 144); - - bl = 4; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, - "SM_VALUE: %u/4 timeslot (~%u microseconds)", - value + 1, (value + 1) * 144); - } - else - { - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo-1, bl); - proto_item_append_text(pi, "SMS Value, SM Value - Bits are not available" ); - } - - /* Additions in release 99 */ - - /* ECSD Multislot Class */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - bo += bl; - if (value == 1) { - bl = 5; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "ECSD Multislot Class"); - if ((value > 0 ) && (value < 19)) { - proto_item_append_text(pi, ": Multislot Class %u", value); - } - else { - proto_item_append_text(pi, ": Reserved"); - } - } - else - { - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo-1, bl); - proto_item_append_text(pi, "ECSD Multislot Class - Bits are not available" ); - } - - /* EGPRS Multislot Class, EGPRS Extended Dynamic Allocation Capability */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - bo += bl; - if (value == 1) { - bl = 5; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "EGPRS Multislot Class: Multislot Class %u", - value); - - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "EGPRS Extended Dynamic Allocation Capability: Extended Dynamic Allocation for EGPRS is%s implemented", - value == 0 ? " not" : ""); - } - else - { - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo-1, bl); - proto_item_append_text(pi, "EGPRS Multislot Class: Multislot Class - Bits are not available"); - } - - /* DTM GPRS Multislot Class */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - bo += bl; - if (value == 1) { - bl = 2; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - dgmsc = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "DTM GPRS Multislot Class: %s", - translate_msrac_dtm_gprs_multislot_class(dgmsc)); - - /* Single slot DTM */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, - "Single Slot DTM: Single slot DTM%s supported", - value == 0 ? " not" : ""); - - /* DTM EGPRS Multislot Class */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - bo += bl; - if (value == 1) { - bl = 2; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - demsc = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "DTM EGPRS Multislot Class: %s", - translate_msrac_dtm_gprs_multislot_class(demsc)); - } - } - proto_item_set_len(ti, get_num_octets_spanned(start_bo, - (guint32) (bo - start_bo))); - } - else { - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "Multislot capability: Same as in the immediately preceding Access capabilities field within this IE"); - } - - /* Additions in release 99 */ - - /* 8PSK Power Capability */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - bo += bl; - if (value == 1) { - bl = 2; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "8PSK Power Capability"); - - if (value == 0) { - proto_item_append_text(pi, ": Reserved"); - } - else{ - proto_item_append_text(pi, ": Power Class E%u", value); - } - proto_item_append_text(pi, ", 8PSK modulation capability in uplink"); - } - - /* COMPACT Interference Measurement Capability */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, - "COMPACT Interference Measurement Capability: %s", - value == 0 ? "Not implemented" : "Implemented"); - - /* Revision level indicator */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "Revision Level Indicator: The ME is Release '%u %s", - value == 0 ? 98 : 99, - value == 0 ? "or older" : "onwards"); - - - /* 3G RAT */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "UMTS FDD Radio Access Technology Capability: UMTS FDD%s supported", - value == 0 ? " not" : ""); - - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "UMTS 3.84 Mcps TDD Radio Access Technology Capability: UMTS 3.84 Mcps TDD%s supported", - value == 0 ? " not" : ""); - - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "CDMA 2000 Radio Access Technology Capability: CDMA 2000%s supported", - value == 0 ? " not" : ""); - - - /* Additions in release 4*/ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "UMTS 1.28 Mcps TDD Radio Access Technology Capability: UMTS 1.28 Mcps TDD%s supported", - value == 0 ? " not" : ""); - - - /* GERAN Feature Package 1 */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "GERAN Feature Package 1: GERAN Feature Package 1%s supported", - value == 0 ? " not" : ""); - - - /* Extended DTM xGPRS Multislot Class */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - bo += bl; - if (value == 1) { - bl = 2; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "Extended DTM GPRS Multi Slot Class: %s", - translate_msrac_extended_dtm_gprs_multislot_class(value, dgmsc)); - - /* XXX: 'This field shall be included only if the MS supports EGPRS DTM'. - How know? */ - bl = 2; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "Extended DTM EGPRS Multi Slot Class: %s", - translate_msrac_extended_dtm_gprs_multislot_class(value, demsc)); - } - - /* Modulation based multislot class support */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "Modulation based multislot class support: %s supported", - value == 0 ? "Not" : ""); - - /* Additions in release 5 */ - - /* High multislot capability */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - bo += bl; - if (value == 1) { - bl = 2; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "High Multislot Capability: %u", value); - /* XXX: Translate? In that case, which values to compare with? - What if Multislot capability struct was not included? */ - } - - /* GERAN Iu Mode Capabilities */ - /* XXX: Interpretation? Length? */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "GERAN Iu Mode Capabilities: %s", - value == 0 ? "Not supported" : "Supported"); - - /* GMSK Multislot Power Profile */ - bl = 2; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "GMSK Multislot Power Profile: GMSK_MULTI_SLOT_POWER_PROFILE %u", - value); - - /* 8PSK Multislot Power Profile */ - /* XXX: 'If the MS does not support 8PSK in the uplink, then it shall - set this field to 00' */ - bl = 2; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "8PSK Multislot Power Profile: 8PSK_MULTI_SLOT_POWER_PROFILE %u", - value); - - /* Additions in release 6 */ - - /* Multiple TBF Capability */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "Multiple TBF Capability: Multiple TBF procedures in A/Gb mode%s supported", - value == 0 ? " not" : ""); - - /* Downlink Advanced Receiver Performance */ - bl = 2; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "Downlink Advanced Receiver Performance: Downlink Advanced Receiver Performance %s supported", - value == 0 ? "not" : "- phase 1"); - - - /* Extended RLC_MAC Control Message Segmentation Capability */ - bl = 1; - if (!struct_bits_exist(start_bo, struct_length, bo, bl)) return; - value = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tree, tvb, bo, bl); - bo += bl; - proto_item_append_text(pi, "Extended RLC/MAC Control Message Segmentation Capability: Extended RLC/MAC Control Message Segmentation%s supported", - value == 0 ? " not" : ""); -} - -static void -decode_msrac_value_part(proto_tree *tree, tvbuff_t *tvb, guint32 bo) { - /* No need to check bi->bssgp_tree here */ - const guint8 ADD_ACC_TECHN = 0x0f; - guint8 att, length, bit, bl; - proto_item *ti, *ti2, *pi; - proto_tree *tf, *tf2; - const char *att_name; - guint32 start_bo; - - start_bo = bo; - ti = bit_proto_tree_add_text(tree, tvb, bo, 8, - "MS RA capability value part"); - /* Temporary length of item */ - tf = proto_item_add_subtree(ti, ett_bssgp_msrac_value_part); - - bl = 4; - att = tvb_get_bits8(tvb, bo, bl); - att_name = translate_msrac_access_technology_type(att); - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl); - proto_item_append_text(pi, "Access Technology Type: %s (%#01x)", att_name, att); - proto_item_append_text(ti, ": Technology Type %s", att_name); - bo += bl; - - bl = 7; - length = tvb_get_bits8(tvb, bo, bl); - pi = bit_proto_tree_add_bit_field8(tf, tvb, bo, bl); - proto_item_append_text(pi, "Length: %u bits", length); - bo += bl; - - if (att == ADD_ACC_TECHN) { - bo++; /* Always '1' */ - ti2 = bit_proto_tree_add_text(tf, tvb, bo, length, - "Additional Access Technologies"); - tf2 = proto_item_add_subtree(ti2, ett_bssgp_msrac_additional_access_technologies); - proto_item_set_len(ti, get_num_octets_spanned(start_bo, 4 + 7 + length + 1 + 1)); - decode_msrac_additional_access_technologies(tf2, tvb, bo, length); - } - else if (att <= 0x0b) { - ti2 = bit_proto_tree_add_text(tf, tvb, bo, length, "Access Capabilities"); - tf2 = proto_item_add_subtree(ti2, ett_bssgp_msrac_access_capabilities); - proto_item_set_len(ti, get_num_octets_spanned(start_bo, 4 + 7 + length + 1)); - decode_msrac_access_capabilities(tf2, tvb, bo, length); - } - /* else unknown Access Technology Type */ - - bo += length; - bit = tvb_get_bits8(tvb, bo, 1); - bo++; - if (bit == 1) { - decode_msrac_value_part(tree, tvb, bo); - } -} -/* - * 11.3.22 MS Radio Access Capability - */ -static void -decode_iei_ms_radio_access_capability(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - proto_tree *tf; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_ms_radio_access_capability); - /* Rest of element coded as the value part defined in - * 3GPP TS 24.008, not including 3GPP TS 24.008 IEI and - * 3GPP TS 24.008 octet length indicator. - * 10.5.5.12a MS Radio Access capability - */ - decode_msrac_value_part(tf, bi->tvb, bi->offset * 8); - bi->offset += ie->value_length; -} -/* - * 11.3.23 OMC Id - */ -static void -decode_iei_omc_id(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - /* XXX: Translation: where in 3GPP TS 12.20? */ - proto_item *ti; - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - proto_item_append_text(ti, ": %s", BSSGP_NOT_DECODED); - } - bi->offset += ie->value_length; -} -/* - * 11.3.24 PDU In Error - */ -static void -decode_iei_pdu_in_error(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - proto_item_append_text(ti, ": Erroneous BSSGP PDU (%u bytes)", - ie->value_length); - } - bi->offset += ie->value_length; -} - -static void -decode_iei_priority(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 MASK_PCI = 0x40; - const guint8 MASK_PRIORITY_LEVEL = 0x3c; - const guint8 MASK_QA = 0x02; - const guint8 MASK_PVI = 0x01; - proto_item *ti, *pi; - proto_tree *tf; - guint8 data, value; - - static const value_string tab_priority_level[] = { - { 0, "Spare" }, - { 1, "Priority Level 1 = highest priority" }, - { 2, "Priority Level 2 = 2nd highest priority" }, - { 3, "Priority Level 3 = 3rd highest priority" }, - { 4, "Priority Level 4 = 4th highest priority" }, - { 5, "Priority Level 5 = 5th highest priority" }, - { 6, "Priority Level 6 = 6th highest priority" }, - { 7, "Priority Level 7 = 7th highest priority" }, - { 8, "Priority Level 8 = 8th highest priority" }, - { 9, "Priority Level 9 = 9th highest priority" }, - { 10, "Priority Level 10 = 10th highest priority" }, - { 11, "Priority Level 11 = 11th highest priority" }, - { 12, "Priority Level 12 = 12th highest priority" }, - { 13, "Priority Level 13 = 13th highest priority" }, - { 14, "Priority Level 14 = lowest priority" }, - { 15, "Priority not used" }, - { 0, NULL }, - }; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_priority); - - data = tvb_get_guint8(bi->tvb, bi->offset); - - value = get_masked_guint8(data, MASK_PCI); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, - MASK_PCI); - proto_item_append_text(pi, "PCI: This allocation request %s preempt an existing connection", - value == 0 ? "shall not" : "may"); - - value = get_masked_guint8(data, MASK_PRIORITY_LEVEL); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_PRIORITY_LEVEL); - proto_item_append_text(pi, "Priority Level: %s", - val_to_str(value, tab_priority_level, "")); - - value = get_masked_guint8(data, MASK_QA); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_QA); - proto_item_append_text(pi, "QA: Queuing%s allowed", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_PVI); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_PVI); - proto_item_append_text(pi, "PVI: This connection %s be preempted by another allocation request", - value == 0 ? "shall not" : "might"); - - bi->offset += ie->value_length; -} -/* - * 11.3.28 QoS Profile - */ -static void -decode_iei_qos_profile(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 MASK_CR_BIT = 0x20; - const guint8 MASK_T_BIT = 0x10; - const guint8 MASK_A_BIT = 0x08; - const guint8 MASK_PRECEDENCE = 0x07; - proto_item *ti, *pi; - proto_tree *tf; - guint8 data, value; - guint16 peak_bit_rate; - - static const value_string tab_precedence_ul[] = { - { 0, "High priority" }, - { 1, "Normal priority" }, - { 2, "Low priority" }, - { 0, NULL }, - }; - - static const value_string tab_precedence_dl[] = { - { 0, "Radio priority 1" }, - { 1, "Radio priority 2" }, - { 2, "Radio priority 3" }, - { 3, "Radio priority 4" }, - { 4, "Radio priority unknown" }, - { 0, NULL }, - }; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_qos_profile); - - peak_bit_rate = tvb_get_ntohs(bi->tvb, bi->offset); - pi = proto_tree_add_text(tf, bi->tvb, bi->offset, 1, "Peak bit rate: "); - if (peak_bit_rate == 0) { - proto_item_append_text(pi, "Best effort"); - } - else { - proto_item_append_text(pi, "%u bits/s", peak_bit_rate * 100); - } - bi->offset += 2; - - data = tvb_get_guint8(bi->tvb, bi->offset); - - value = get_masked_guint8(data, MASK_CR_BIT); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_CR_BIT); - proto_item_append_text(pi, "C/R: The SDU %s command/response frame type", - value == 0 ? "contains" : "does not contain"); - - value = get_masked_guint8(data, MASK_T_BIT); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_T_BIT); - proto_item_append_text(pi, "T: The SDU contains %s", - value == 0 ? "signalling (e.g. related to GMM)" : "data"); - - value = get_masked_guint8(data, MASK_A_BIT); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_A_BIT); - proto_item_append_text(pi, "A: Radio interface uses RLC/MAC %s functionality", - value == 0 ? "ARQ " : "UNITDATA "); - - value = get_masked_guint8(data, MASK_PRECEDENCE); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_PRECEDENCE); - proto_item_append_text(pi, "Precedence: "); - - if (bi->ul_data) { - proto_item_append_text(pi, "%s", val_to_str(value, tab_precedence_ul, - "Reserved (Low priority)")); - } - else { - proto_item_append_text(pi, "%s", val_to_str(value, tab_precedence_dl, - "Reserved (Radio priority 3)")); - } - proto_item_append_text(pi, " (%#x)", value); - bi->offset++; -} -/* - * 11.3.29 Radio Cause - */ -static void -decode_iei_radio_cause(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - guint8 value; - - static const value_string tab_radio_cause[] = { - { 0x00, "Radio contact lost with the MS" }, - { 0x01, "Radio link quality insufficient to continue communication" }, - { 0x02, "Cell reselection ordered" }, - { 0x03, "Cell reselection prepare" }, - { 0x04, "Cell reselection failure" }, - { 0, NULL }, - /* Otherwise "Reserved (Radio contact lost with the MS)" */ - }; - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - value = tvb_get_guint8(bi->tvb, bi->offset); - proto_item_append_text(ti, ": %s (%#02x)", - val_to_str(value, tab_radio_cause, "Reserved (Radio contact lost with the MS)"), - value); - } - bi->offset += ie->value_length; -} - -static void -decode_iei_ra_cap_upd_cause(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - guint8 value; - - static const value_string tab_cause_value[] = { - { 0x00, "OK, RA capability IE present" }, - { 0x01, "TLLI unknown in SGSN" }, - { 0x02, "No RA capabilities or IMSI available for this MS" }, - { 0, NULL }, - /* Otherwise "Reserved (TLLI unknown in SGSN)" */ - }; - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - value = tvb_get_guint8(bi->tvb, bi->offset); - proto_item_append_text(ti, ": %s (%#2x)", - val_to_str(value, tab_cause_value, "Reserved (TLLI unknown in SGSN)"), - value); - } - bi->offset += ie->value_length; -} - -static void -decode_iei_routing_area(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - proto_tree *tf; - char *rai; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_routing_area); - - rai = decode_rai(bi, tf); - proto_item_append_text(ti, ": RAI %s", rai); -} - -static void -decode_iei_tlli(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - proto_tree *tf; - - guint32 tlli; - tlli = tvb_get_ntohl(bi->tvb, bi->offset); - - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - proto_item_append_text(ti, ": %#04x", tlli); - /* By Stefan Boman LN/Ericsson 2006-07-14 -- - * Commented the following four lines. Preventing redundant data - */ - /* - ti = bssgp_proto_tree_add_ie(ie, bi, bi->offset); - */ - /* If we want to keep the posibillity to filter on ie:s without a Tag and the ie "content" - * this is how it has to be done. - */ - tf = proto_item_add_subtree(ti, ett_bssgp_tlli); - - proto_tree_add_item(tf, hf_bssgp_tlli, - bi->tvb, bi->offset, 4, ENC_BIG_ENDIAN); - - bi->offset += 4; - - col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP, - "TLLI %#4x", tlli); - - decode_nri(bi->bssgp_tree, bi, tlli); -} - -static void -decode_iei_tmsi(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - proto_tree *tf; - guint32 tmsi; - - tmsi = tvb_get_ntohl(bi->tvb, bi->offset); - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - proto_item_append_text(ti, ": %#04x", tmsi); - - ti = bssgp_proto_tree_add_ie(ie, bi, bi->offset); - tf = proto_item_add_subtree(ti, ett_bssgp_tmsi_ptmsi); - - proto_tree_add_item(tf, hf_bssgp_tmsi_ptmsi, - bi->tvb, bi->offset, 4, ENC_BIG_ENDIAN); - } - bi->offset += 4; - - col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP, - "(P)TMSI %#4x", tmsi); - - decode_nri(bi->bssgp_tree, bi, tmsi); -} - -static void -decode_iei_trigger_id(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - /* XXX: value is 20 octets long! How add/show? */ - proto_item *ti; - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - } - bi->offset += ie->value_length; -} - -static void -proto_tree_add_lsa_id(build_info_t *bi, proto_tree *tree) { - guint32 data, lsa_id; - proto_item *pi; - - data = tvb_get_ntoh24(bi->tvb, bi->offset); - lsa_id = data >> 1; - - pi = proto_tree_add_text(tree, bi->tvb, bi->offset, 3, - "LSA ID: %#03x (%s)", lsa_id, - data & 1 ? - "Universal LSA" : "PLMN significant number"); - bi->offset += 3; -} - -static void -decode_iei_lsa_identifier_list(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 MASK_EP = 0x01; - proto_item *ti, *pi; - proto_tree *tf; - int num_lsa_ids, i; - guint32 value; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_lsa_identifier_list); - - value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_EP); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_EP); - proto_item_append_text(pi, "EP: The escape PLMN is%s broadcast", - value == 0 ? " not" : ""); - bi->offset++; - - num_lsa_ids = (ie->value_length - 1) / 3; - - for (i = 0; i < num_lsa_ids; i++) { - proto_tree_add_lsa_id(bi, tf); - } -} - -static void -decode_iei_lsa_information(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 MASK_LSA_ONLY = 0x01; - const guint8 MASK_ACT = 0x20; - const guint8 MASK_PREF = 0x10; - const guint8 MASK_PRIORITY = 0x0f; - proto_item *ti, *ti2, *pi; - proto_tree *tf, *tf2; - int num_lsa_infos, i; - guint8 data, value; - - static const value_string tab_priority[] = { - { 0, "Priority 1 = lowest priority" }, - { 1, "Priority 2 = 2nd lowest priority" }, - { 2, "Priority 3 = 3rd lowest priority" }, - { 3, "Priority 4 = 4th lowest priority" }, - { 4, "Priority 5 = 5th lowest priority" }, - { 5, "Priority 6 = 6th lowest priority" }, - { 6, "Priority 7 = 7th lowest priority" }, - { 7, "Priority 8 = 8th lowest priority" }, - { 8, "Priority 9 = 9th lowest priority" }, - { 9, "Priority 10 = 10th lowest priority" }, - { 10, "Priority 11 = 11th lowest priority" }, - { 11, "Priority 12 = 12th lowest priority" }, - { 12, "Priority 13 = 13th lowest priority" }, - { 13, "Priority 14 = 14th lowest priority" }, - { 14, "Priority 15 = 15th lowest priority" }, - { 15, "Priority 16 = highest priority" }, - { 0, NULL }, - }; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_lsa_information); - - value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_LSA_ONLY); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_LSA_ONLY); - proto_item_append_text(pi, "LSA Only: %s", - value == 0 ? - "The subscriber has only access to the LSAs that are defined by the LSA information element" : - "Allow an emergency call"); - bi->offset++; - - num_lsa_infos = (ie->value_length - 1) / 4; - - for (i = 0; i < num_lsa_infos; i++) { - ti2 = proto_tree_add_text(tf, bi->tvb, bi->offset, 4, - "LSA Identification and attributes %u", i + 1); - tf2 = proto_item_add_subtree(ti2, ett_bssgp_lsa_information_lsa_identification_and_attributes); - - data = tvb_get_guint8(bi->tvb, bi->offset); - - value = get_masked_guint8(data, MASK_ACT); - pi = proto_tree_add_bitfield8(tf2, bi->tvb, bi->offset, MASK_ACT); - proto_item_append_text(pi, "Act: The subscriber %s active mode support in the LSA", - value == 0 ? "does not have" : "has"); - - value = get_masked_guint8(data, MASK_PREF); - pi = proto_tree_add_bitfield8(tf2, bi->tvb, bi->offset, MASK_PREF); - proto_item_append_text(pi, "Pref: The subscriber %s preferential access in the LSA", - value == 0 ? "does not have" : "has"); - - value = get_masked_guint8(data, MASK_PRIORITY); - pi = proto_tree_add_bitfield8(tf2, bi->tvb, bi->offset, MASK_PRIORITY); - proto_item_append_text(pi, "Priority: %s", - val_to_str(value, tab_priority, "")); - bi->offset++; - - proto_tree_add_lsa_id(bi, tf2); - } -} - -static void -decode_iei_gprs_timer(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 MASK_UNIT_VALUE = 0xe0; - const guint8 MASK_TIMER_VALUE = 0x1f; - proto_item *ti; - guint8 data, value; - - static const value_string tab_unit_value[] = { - { 0, "incremented in multiples of 2 s" }, - { 1, "incremented in multiples of 1 minute" }, - { 2, "incremented in multiples of decihours" }, - { 3, "incremented in multiples of 500 msec" }, - { 7, "the timer does not expire" }, - { 0, NULL}, - /* Otherwise "incremented in multiples of 1 minute" */ - }; - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - data = tvb_get_guint8(bi->tvb, bi->offset); - value = get_masked_guint8(data, MASK_TIMER_VALUE); - proto_item_append_text(ti, ": %u", value); - - value = get_masked_guint8(data, MASK_UNIT_VALUE); - proto_item_append_text(ti, ", %s", - val_to_str(value, tab_unit_value, - "incremented in multiples of 1 minute")); - } - bi->offset += ie->value_length; -} - -static void -decode_iei_abqp(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 MASK_DELAY_CLASS = 0x38; - const guint8 MASK_RELIABILITY_CLASS = 0x07; - const guint8 MASK_PEAK_THROUGHPUT = 0xf0; - const guint8 MASK_PRECEDENCE_CLASS = 0x07; - const guint8 MASK_MEAN_THROUGHPUT = 0x1f; - const guint8 MASK_TRAFFIC_CLASS = 0xe0; - const guint8 MASK_DELIVERY_ORDER = 0x18; - const guint8 MASK_DELIVERY_OF_ERRONEOUS_SDU = 0x07; - const guint8 MASK_RESIDUAL_BER = 0xf0; - const guint8 MASK_SDU_ERROR_RATIO = 0x0f; - const guint8 MASK_TRANSFER_DELAY = 0xfc; - const guint8 MASK_TRAFFIC_HANDLING_PRIORITY = 0x03; - const guint8 MASK_SIGNALLING_INDICATION = 0x10; - const guint8 MASK_SOURCE_STATISTICS_DESCRIPTOR = 0x0f; - const guint8 TRAFFIC_CLASS_CONVERSATIONAL = 1; - const guint8 TRAFFIC_CLASS_STREAMING = 2; - const guint8 TRAFFIC_CLASS_INTERACTIVE = 3; - const guint8 TRAFFIC_CLASS_BACKGROUND = 4; - guint8 data, value, traffic_class; - proto_item *ti, *pi; - proto_tree *tf; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_abqp); - - data = tvb_get_guint8(bi->tvb, bi->offset); - - value = get_masked_guint8(data, MASK_DELAY_CLASS); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_DELAY_CLASS); - proto_item_append_text(pi, "Delay Class: %s (%#x)", - translate_abqp_delay_class(value, bi), value); - - value = get_masked_guint8(data, MASK_RELIABILITY_CLASS); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, - MASK_RELIABILITY_CLASS); - proto_item_append_text(pi, "Reliability Class: %s (%#x)", - translate_abqp_reliability_class(value, bi), value); - bi->offset++; - /* Octet 4 */ - data = tvb_get_guint8(bi->tvb, bi->offset); - - value = get_masked_guint8(data, MASK_PEAK_THROUGHPUT); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, - MASK_PEAK_THROUGHPUT); - proto_item_append_text(pi, "Peak Throughput: %s (%#x)", - translate_abqp_peak_throughput(value, bi), value); - - value = get_masked_guint8(data, MASK_PRECEDENCE_CLASS); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, - MASK_PRECEDENCE_CLASS); - proto_item_append_text(pi, "Precedence Class: %s (%#x)", - translate_abqp_precedence_class(value, bi), value); - bi->offset++; - /* Octet 5 */ - data = tvb_get_guint8(bi->tvb, bi->offset); - - value = get_masked_guint8(data, MASK_MEAN_THROUGHPUT); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, - MASK_MEAN_THROUGHPUT); - proto_item_append_text(pi, "Mean Throughput: %s (%#02x)", - translate_abqp_mean_throughput(value, bi), value); - /* - * A QoS IE received without octets 6-16, without octets 14-16, or without octets 15-16 shall be accepted by the - * receiving entity. - */ - bi->offset++; - if (ie->value_length == 3) - return; - /* Octet 6 */ - data = tvb_get_guint8(bi->tvb, bi->offset); - - traffic_class = get_masked_guint8(data, MASK_TRAFFIC_CLASS); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_TRAFFIC_CLASS); - proto_item_append_text(pi, "Traffic Class: %s (%#x)", - translate_abqp_traffic_class(traffic_class, bi), - value); - if ((traffic_class == TRAFFIC_CLASS_INTERACTIVE) || - (traffic_class == TRAFFIC_CLASS_BACKGROUND)) { - proto_item_append_text(pi, " (ignored)"); - } - - value = get_masked_guint8(data, MASK_DELIVERY_ORDER); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_DELIVERY_ORDER); - proto_item_append_text(pi, "Delivery Order: %s (%#x)", - translate_abqp_delivery_order(value, bi), value); - - value = get_masked_guint8(data, MASK_DELIVERY_OF_ERRONEOUS_SDU); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, - MASK_DELIVERY_OF_ERRONEOUS_SDU); - proto_item_append_text(pi, "Delivery of Erroneous SDU: %s (%#x)", - translate_abqp_delivery_of_erroneous_sdu(value, bi), - value); - bi->offset++; - /* Octet 7 */ - - value = tvb_get_guint8(bi->tvb, bi->offset); - proto_tree_add_text(tf, bi->tvb, bi->offset, 1, - "Maximum SDU Size: %s", - translate_abqp_max_sdu_size(value, bi)); - /* Octet 8 */ - bi->offset++; - - value = tvb_get_guint8(bi->tvb, bi->offset); - proto_tree_add_text(tf, bi->tvb, bi->offset, 1, - "Maximum bit rate for uplink: %s", - translate_abqp_max_bit_rate_for_ul(value, bi)); - /* Octet 9 */ - bi->offset++; - - value = tvb_get_guint8(bi->tvb, bi->offset); - proto_tree_add_text(tf, bi->tvb, bi->offset, 1, - "Maximum bit rate for downlink: %s", - translate_abqp_max_bit_rate_for_dl(value, bi)); - /* Octet 10 */ - bi->offset++; - data = tvb_get_guint8(bi->tvb, bi->offset); - - value = get_masked_guint8(data, MASK_RESIDUAL_BER); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_RESIDUAL_BER); - proto_item_append_text(pi, "Residual BER: %s (%#x)", - translate_abqp_residual_ber(value, bi), value); - - value = get_masked_guint8(data, MASK_SDU_ERROR_RATIO); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, - MASK_SDU_ERROR_RATIO); - proto_item_append_text(pi, "SDU Error Ratio: %s (%#x)", - translate_abqp_sdu_error_ratio(value, bi), value); - /* Octet 11 */ - bi->offset++; - data = tvb_get_guint8(bi->tvb, bi->offset); - - value = get_masked_guint8(data, MASK_TRANSFER_DELAY); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_TRANSFER_DELAY); - proto_item_append_text(pi, "Transfer Delay: %s (%#02x)", - translate_abqp_transfer_delay(value, bi), value); - - value = get_masked_guint8(data, MASK_TRAFFIC_HANDLING_PRIORITY); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, - MASK_TRAFFIC_HANDLING_PRIORITY); - proto_item_append_text(pi, "Traffic Handling Priority: %s (%#x)", - translate_abqp_traffic_handling_priority(value, bi), - value); - if ((traffic_class == TRAFFIC_CLASS_CONVERSATIONAL) || - (traffic_class == TRAFFIC_CLASS_STREAMING) || - (traffic_class == TRAFFIC_CLASS_BACKGROUND)) { - proto_item_append_text(pi, " (ignored)"); - } - /* Octet 12 */ - bi->offset++; - - value = tvb_get_guint8(bi->tvb, bi->offset); - proto_tree_add_text(tf, bi->tvb, bi->offset, 1, - "Guaranteed bit rate for uplink: %s", - translate_abqp_guaranteed_bit_rate_for_ul(value, bi)); - /* Octet 13 */ - bi->offset++; - - value = tvb_get_guint8(bi->tvb, bi->offset); - proto_tree_add_text(tf, bi->tvb, bi->offset, 1, - "Guaranteed bit rate for downlink: %s", - translate_abqp_guaranteed_bit_rate_for_dl(value, bi)); - /* - * A QoS IE received without octets 6-16, without octets 14-16, or without octets 15-16 shall be accepted by the - * receiving entity. - */ - /* Octet 14 */ - bi->offset++; - if (ie->value_length == 11) - return; - - data = tvb_get_guint8(bi->tvb, bi->offset); - - value = get_masked_guint8(data, MASK_SIGNALLING_INDICATION); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, - MASK_SIGNALLING_INDICATION); - proto_item_append_text(pi, "Signalling Indication: %s for signalling traffic", - value == 0 ? "Not optimized" : "Optimized"); - if ((traffic_class == TRAFFIC_CLASS_CONVERSATIONAL) || - (traffic_class == TRAFFIC_CLASS_STREAMING) || - (traffic_class == TRAFFIC_CLASS_BACKGROUND)) { - proto_item_append_text(pi, " (ignored)"); - } - - value = get_masked_guint8(data, MASK_SOURCE_STATISTICS_DESCRIPTOR); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, - MASK_SOURCE_STATISTICS_DESCRIPTOR); - proto_item_append_text(pi, "Source Statistics Descriptor: %s (%#x)", - translate_abqp_source_statistics_descriptor(value, bi), - value); - if ((traffic_class == TRAFFIC_CLASS_INTERACTIVE) || - (traffic_class == TRAFFIC_CLASS_BACKGROUND)) { - proto_item_append_text(pi, " (ignored)"); - } - /* - * A QoS IE received without octets 6-16, without octets 14-16, or without octets 15-16 shall be accepted by the - * receiving entity. - */ - /* Octet 15 */ - bi->offset++; - if (ie->value_length == 12) - return; - - value = tvb_get_guint8(bi->tvb, bi->offset); - proto_tree_add_text(tf, bi->tvb, bi->offset, 1, - "Maximum bit rate for downlink (extended): %s", - translate_abqp_max_bit_rate_for_dl_extended(value, bi)); - /* Octet 16 */ - bi->offset++; - - value = tvb_get_guint8(bi->tvb, bi->offset); - proto_tree_add_text(tf, bi->tvb, bi->offset, 1, - "Guaranteed bit rate for downlink (extended): %s", - translate_abqp_guaranteed_bit_rate_for_dl_extended(value, bi)); - bi->offset++; -} - -static void -decode_iei_feature_bitmap(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 MASK_ENHANCED_RADIO_STATUS = 0x40; - const guint8 MASK_PFC_FC = 0x20; - const guint8 MASK_RIM = 0x10; - const guint8 MASK_LCS = 0x08; - const guint8 MASK_INR = 0x04; - const guint8 MASK_CBL = 0x02; - const guint8 MASK_PFC = 0x01; - proto_item *ti, *pi; - proto_tree *tf; - guint8 data, value; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_feature_bitmap); - - data = tvb_get_guint8(bi->tvb, bi->offset); - - value = get_masked_guint8(data, MASK_ENHANCED_RADIO_STATUS); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, - MASK_ENHANCED_RADIO_STATUS); - proto_item_append_text(pi, "Enhanced Radio Status: Enhanced Radio Status Procedures%s supported", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_PFC_FC); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_PFC_FC); - proto_item_append_text(pi, "PFC_FC: PFC Flow Control Procedures%s supported", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_RIM); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_RIM); - proto_item_append_text(pi, "RIM: RAN Information Management (RIM) Procedures%s supported", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_LCS); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_LCS); - proto_item_append_text(pi, "LCS: LCS Procedures%s supported", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_INR); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_INR); - proto_item_append_text(pi, "INR: Inter-NSE re-routing%s supported", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_CBL); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_CBL); - proto_item_append_text(pi, "CBL: Current Bucket Level Procedures%s supported", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_PFC); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_PFC); - proto_item_append_text(pi, "PFC: Packet Flow Context Procedures%s supported", - value == 0 ? " not" : ""); - - bi->offset += ie->value_length; -} - -static void -decode_iei_bucket_full_ratio(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - bssgp_pi_append_bucket_full_ratio(ti, bi->tvb, bi->offset); - } - bi->offset += ie->value_length; -} - -static void -decode_iei_service_utran_cco(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 MASK_SERVICE_UTRAN_CCO = 0x07; - proto_item *ti; - guint8 data, value; - - static const value_string tab_service_utran_cco[] = { - { 0, "Network initiated cell change order procedure to UTRAN should be performed" }, - { 1, "Network initiated cell change order procedure to UTRAN should not be performed" }, - { 2, "Network initiated cell change order procedure to UTRAN shall not be performed" }, - { 3, " If received, shall be interpreted as no information available (bits 4-5 valid)" }, - { 0, NULL }, - /* Otherwise "No information available" */ - }; - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - data = tvb_get_guint8(bi->tvb, bi->offset); - value = get_masked_guint8(data, MASK_SERVICE_UTRAN_CCO); - proto_item_append_text(ti, ": %s (%#02x)", - val_to_str(value, tab_service_utran_cco, - "No information available"), - value); - } - bi->offset += ie->value_length; -} - -static void -decode_iei_nsei(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti, *hidden_item; - guint16 nsei; - - nsei = tvb_get_ntohs(bi->tvb, bi->offset); - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - proto_item_append_text(ti, ": %u", nsei); - hidden_item = proto_tree_add_item(bi->bssgp_tree, hf_bssgp_nsei, - bi->tvb, bi->offset, 2, ENC_BIG_ENDIAN); - PROTO_ITEM_SET_HIDDEN(hidden_item); - } - bi->offset += ie->value_length; - - col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP, - "NSEI %u", nsei); -} - -static void -decode_iei_lcs_qos(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 MASK_VERT = 0x01; - const guint8 MASK_XA = 0x80; - const guint8 MASK_ACCURACY = 0x7f; - const guint8 MASK_RT = 0xc0; - proto_item *ti, *pi; - proto_tree *tf; - guint8 data, value, vert; - - static const value_string tab_rt[] = { - { 0, "Response time is not specified" }, - { 1, "Low delay" }, - { 2, "Delay tolerant" }, - { 3, "Reserved" }, - { 0, NULL }, - }; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_lcs_qos); - - data = tvb_get_guint8(bi->tvb, bi->offset); - vert = get_masked_guint8(data, MASK_VERT); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_VERT); - proto_item_append_text(pi, "VERT: Vertical coordinate is%s requested", - vert == 0 ? " not" : ""); - bi->offset++; - - data = tvb_get_guint8(bi->tvb, bi->offset); - - value = get_masked_guint8(data, MASK_XA); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_XA); - proto_item_append_text(pi, "HA: Horizontal Accuracy is%s specified", - value == 0 ? " not" : ""); - - if (value == 1) { - value = get_masked_guint8(data, MASK_ACCURACY); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_ACCURACY); - proto_item_append_text(pi, "Horizontal Accuracy: %.1f m", - 10 * (pow(1.1, (double)value) - 1)); - } - bi->offset++; - - data = tvb_get_guint8(bi->tvb, bi->offset); - - if (vert == 1) { - value = get_masked_guint8(data, MASK_XA); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_XA); - proto_item_append_text(pi, "VA: Vertical Accuracy is%s specified", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_ACCURACY); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_ACCURACY); - proto_item_append_text(pi, "Vertical Accuracy: %.1f m", - 45 * (pow(1.025, (double)value) - 1)); - } - bi->offset++; - - data = tvb_get_guint8(bi->tvb, bi->offset); - value = get_masked_guint8(data, MASK_RT); - - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_RT); - proto_item_append_text(pi, "RT: %s", - val_to_str(value, tab_rt, "")); - bi->offset++; -} - -static void -decode_iei_lcs_client_type(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 MASK_CATEGORY = 0xf0; - const guint8 MASK_SUBTYPE = 0x0f; - proto_item *ti, *pi; - proto_tree *tf; - guint8 data, category, subtype; - - static const value_string tab_category[] = { - { 0, "Value Added Client" }, - /* { 1, ??? XXX }, */ - { 2, "PLMN Operator" }, - { 3, "Emergency Services" }, - { 4, "Lawful Intercept Services" }, - { 0, NULL }, - /* Otherwise "Reserved" */ - }; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_lcs_client_type); - - data = tvb_get_guint8(bi->tvb, bi->offset); - - category = get_masked_guint8(data, MASK_CATEGORY); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_CATEGORY); - proto_item_append_text(pi, "Category: %s (%#x)", - val_to_str(category, tab_category, "Reserved"), - category); - - subtype = get_masked_guint8(data, MASK_SUBTYPE); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_SUBTYPE); - proto_item_append_text(pi, "Subtype: "); - - switch (category) { - case 0: - if (subtype == 0) { - proto_item_append_text(pi, "Unspecified"); break; - } - else { - proto_item_append_text(pi, "Reserved"); break; - } - /* case 1: ??? XXX*/ - case 2: - switch (subtype) { - case 0: proto_item_append_text(pi, "Unspecified"); break; - case 1: proto_item_append_text(pi, "Broadcast service"); break; - case 2: proto_item_append_text(pi, "O&M"); break; - case 3: proto_item_append_text(pi, "Anonymous statistics"); break; - case 4: proto_item_append_text(pi, "Target MS service support node"); break; - default: proto_item_append_text(pi, "Reserved"); break; - } - break; - case 3: - case 4: - if (subtype == 0) { - proto_item_append_text(pi, "Unspecified"); break; - } - else { - proto_item_append_text(pi, "Reserved"); break; - } - default: /* Not category == 1! */ - proto_item_append_text(pi, "Reserved"); break; - } - - bi->offset++; -} - -static void -decode_iei_requested_gps_assistance_data(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 MASK_A = 0x01; - const guint8 MASK_B = 0x02; - const guint8 MASK_C = 0x04; - const guint8 MASK_D = 0x08; - const guint8 MASK_E = 0x10; - const guint8 MASK_F = 0x20; - const guint8 MASK_G = 0x40; - const guint8 MASK_H = 0x80; - const guint8 MASK_I = 0x01; - const guint8 MASK_NSAT = 0xf0; - const guint8 MASK_T_TOE_LIMIT = 0x0f; - const guint8 MASK_SAT_ID =0x3f; - proto_tree *tf, *tf2; - proto_item *ti, *ti2, *pi; - guint8 data, value, d, nsat; - guint16 gps_week; - int i; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_requested_gps_assistance_data); - - data = tvb_get_guint8(bi->tvb, bi->offset); - - value = get_masked_guint8(data, MASK_A); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_A); - proto_item_append_text(pi, "A: Almanac is%s srequested", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_B); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_B); - proto_item_append_text(pi, "B: UTC Model is%s requested", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_C); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_C); - proto_item_append_text(pi, "C: Ionospheric Model is%s requested", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_D); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_D); - proto_item_append_text(pi, "D: Navigation Model is%s requested", - value == 0 ? " not" : ""); - d = value; - - value = get_masked_guint8(data, MASK_E); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_E); - proto_item_append_text(pi, "E: DGPS Corrections are%s requested", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_F); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_F); - proto_item_append_text(pi, "F: Reference Location is%s requested", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_G); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_G); - proto_item_append_text(pi, "G: Reference Time is%s requested", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_H); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_H); - proto_item_append_text(pi, "H: Acquisition Assistance is%s requested", - value == 0 ? " not" : ""); - - bi->offset++; - - value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_I); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_I); - proto_item_append_text(pi, "I: Real-Time Integrity is%s requested", - value == 0 ? " not" : ""); - if (d == 0) return; - - data = tvb_get_guint8(bi->tvb, bi->offset); - gps_week = (data & 0xc0) << 2; - data = tvb_get_guint8(bi->tvb, bi->offset + 1); - gps_week += data; - proto_tree_add_text(tf, bi->tvb, bi->offset, 2, - "GPS Week: %u", gps_week); - bi->offset += 2; - - value = tvb_get_guint8(bi->tvb, bi->offset); - proto_tree_add_text(tf, bi->tvb, bi->offset, 1, - "GPS Toe: %u", value); - bi->offset++; - - data = tvb_get_guint8(bi->tvb, bi->offset); - nsat = get_masked_guint8(data, MASK_NSAT); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_NSAT); - proto_item_append_text(pi, "NSAT: %u", value); - - value = get_masked_guint8(data, MASK_T_TOE_LIMIT); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_T_TOE_LIMIT); - proto_item_append_text(pi, "T-Toe Limit: %u", value); - bi->offset++; - - for (i = 0; i < nsat; i++) { - ti2 = proto_tree_add_text(tf, bi->tvb, bi->offset, 2, "Satellite %u", i); - tf2 = proto_item_add_subtree(ti2, ett_bssgp_requested_gps_assistance_data_satellite); - - value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_SAT_ID); - pi = proto_tree_add_bitfield8(tf2, bi->tvb, bi->offset, MASK_SAT_ID); - proto_item_append_text(pi, "SatId: %u", value); - proto_item_append_text(ti2, ": Id %u", value); - bi->offset++; - - value = tvb_get_guint8(bi->tvb, bi->offset); - proto_tree_add_text(tf2, bi->tvb, bi->offset, 1, - "IODE: %u", value); - proto_item_append_text(ti2, ", IODE %u", value); - bi->offset++; - } -} - -static void -decode_iei_location_type(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 LOCATION_ASSISTANCE = 1; - const guint8 DECIPHERING_KEYS = 2; - proto_item *ti; - proto_tree *tf; - guint8 value; - - static const value_string tab_location_information[] = { - { 0, "Current geographic location" }, - { 1, "Location assistance information for the target MS" }, - { 2, "Deciphering keys for broadcast assistance data for the target MS" }, - { 0, NULL }, - /* Otherwise "Reserved" */ - }; - - static const value_string tab_positioning_method[] = { - { 0, "Reserved" }, - { 1, "Mobile Assisted E-OTD" }, - { 2, "Mobile Based E-OTD" }, - { 3, "Assisted GPS" }, - { 0, NULL }, - /* Otherwise "Reserved" */ - }; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_location_type); - - value = tvb_get_guint8(bi->tvb, bi->offset); - proto_tree_add_text(tf, bi->tvb, bi->offset, 1, "Location Information: %s", - val_to_str(value, tab_location_information, - "Reserved")); - bi->offset++; - - if ((value == LOCATION_ASSISTANCE) || (value == DECIPHERING_KEYS)) { - value = tvb_get_guint8(bi->tvb, bi->offset); - proto_tree_add_text(tf, bi->tvb, bi->offset, 1, "Positioning Method: %s", - val_to_str(value, tab_positioning_method, - "Reserved")); - bi->offset++; - } -} - -static void -decode_iei_location_estimate(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - /* XXX: Which paragraph in 3GPP TS 23.032?*/ - proto_item *ti; - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - proto_item_append_text(ti, ": %s", BSSGP_NOT_DECODED); - } - if (ie->value_length != BSSGP_UNKNOWN) { - bi->offset += ie->value_length; - } -} - -static void -decode_iei_positioning_data(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 MASK_PDD = 0x0f; - const guint8 MASK_METHOD = 0xf8; - const guint8 MASK_USAGE = 0x07; - proto_item *ti, *pi; - proto_tree *tf; - guint8 data, value, i, num_methods; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_positioning_data); - - value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_PDD); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_PDD); - proto_item_append_text(pi, "Positioning Data Discriminator: %s", - value == 0 ? - "Indicate usage of each positioning method that was attempted either successfully or unsuccessfully" : - "Reserved"); - bi->offset++; - - num_methods = ie->value_length - 1; - for (i = 0; i < num_methods; i++) { - data = tvb_get_guint8(bi->tvb, bi->offset); - - value = get_masked_guint8(data, MASK_METHOD); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_METHOD); - proto_item_append_text(pi, "Method: "); - - switch (value) { - case 0: proto_item_set_text(pi, "Timing Advance"); break; - case 1: proto_item_set_text(pi, "Reserved"); break; - case 2: proto_item_set_text(pi, "Reserved"); break; - case 3: proto_item_set_text(pi, "Mobile Assisted E-OTD"); break; - case 4: proto_item_set_text(pi, "Mobile Based E-OTD"); break; - case 5: proto_item_set_text(pi, "Mobile Assisted GPS"); break; - case 6: proto_item_set_text(pi, "Mobile Based GPS"); break; - case 7: proto_item_set_text(pi, "Conventional GPS"); break; - case 8: proto_item_set_text(pi, "U-TDOA"); break; - default: - if ((value >= 9) && (value <= 0x0f)) { - proto_item_set_text(pi, "Reserved for GSM"); - } - else { - proto_item_set_text(pi, "Reserved for network specific positioning methods"); - } - } - proto_item_append_text(pi, " (%#02x)", value); /* Method */ - - value = get_masked_guint8(data, MASK_USAGE); - - switch (value) { - case 0: proto_item_append_text(pi, " attempted unsuccessfully due to failure or interruption "); break; - case 1: proto_item_append_text(pi, " attempted successfully: results not used to generate location"); break; - case 2: proto_item_append_text(pi, " attempted successfully: results used to verify but not generate location"); break; - case 3: proto_item_append_text(pi, " attempted successfully: results used to generate location"); break; - case 4: proto_item_append_text(pi, " attempted successfully: case where MS supports multiple mobile based" - " positioning methods and the actual method or methods used by the MS cannot be determined"); break; - default: ; /* ??? */ - } - proto_item_append_text(pi, " (%#x)", value); /* Usage */ - bi->offset++; - } -} - -static void -decode_iei_deciphering_keys(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 MASK_KEY_FLAG = 0x01; - proto_item *ti, *pi; - proto_tree *tf; - guint8 data, value; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_deciphering_keys); - - data = tvb_get_guint8(bi->tvb, bi->offset); - value = get_masked_guint8(data, MASK_KEY_FLAG); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_KEY_FLAG); - proto_item_append_text(pi, "Ciphering Key Flag: %u", value); - bi->offset++; - - proto_tree_add_text(tf, bi->tvb, bi->offset, 7, - "Current Deciphering Key Value"); - bi->offset += 7; - - proto_tree_add_text(tf, bi->tvb, bi->offset, 7, - "Next Deciphering Key Value"); - bi->offset += 7; -} - -static void -decode_iei_lcs_priority(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - /* XXX: coding (3GPP TS 29.002 7.6.11.7)? */ - proto_item *ti; - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - proto_item_append_text(ti, ": %s", BSSGP_NOT_DECODED); - } - bi->offset += ie->value_length; -} - -static void -decode_iei_lcs_cause(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - proto_tree *tf; - guint8 value; - - static const value_string tab_cause_value[] = { - { 0, "Unspecified" }, - { 1, "System failure" }, - { 2, "Protocol error" }, - { 3, "Data missing in position request" }, - { 4, "Unexpected value in position request" }, - { 5, "Position method failure" }, - { 6, "Target MS unreachable" }, - { 7, "Location request aborted" }, - { 8, "Facility not supported" }, - { 9, "Inter-BSC handover ongoing" }, - { 10, "Intra-BSC handover ongoing" }, - { 11, "Congestion" }, - { 12, "Inter NSE cell change" }, - { 13, "Routing area update" }, - { 14, "PTMSI reallocation" }, - { 15, "Suspension of GPRS services" }, - { 0, NULL }, - /* Otherwise "Unspecified" */ - }; - - static const value_string tab_diagnostic_value[] = { - { 0, "Congestion" }, - { 1, "Insufficient resources" }, - { 2, "Insufficient measurement data" }, - { 3, "Inconsistent measurement data" }, - { 4, "Location procedure not completed" }, - { 5, "Location procedure not supported by target MS" }, - { 6, "QoS not attainable" }, - { 7, "Position method not available in network" }, - { 8, "Position method not available in location area" }, - { 0, NULL }, - /* Otherwise "Unrecognized => ignored" */ - }; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - value = tvb_get_guint8(bi->tvb, bi->offset); - - if (ie->value_length == 1) { - /* Diagnostic value not included */ - proto_item_append_text(ti, ": %s (%#02x)", - val_to_str(value, tab_cause_value, "Unspecified"), - value); - bi->offset++; - return; - } - - tf = proto_item_add_subtree(ti, ett_bssgp_lcs_cause); - - proto_tree_add_text(tf, bi->tvb, bi->offset, 1, ": %s (%#02x)", - val_to_str(value, tab_cause_value, "Unspecified"), - value); - bi->offset++; - - value = tvb_get_guint8(bi->tvb, bi->offset); - proto_tree_add_text(tf, bi->tvb, bi->offset, 1, ": %s (%#02x)", - val_to_str(value, tab_diagnostic_value, - "Unrecognized => ignored"), - value); - bi->offset++; -} - -static void -decode_iei_lcs_capability(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 MASK_OTD_A = 0x10; - const guint8 MASK_OTD_B = 0x08; - const guint8 MASK_GPS_A = 0x04; - const guint8 MASK_GPS_B = 0x02; - const guint8 MASK_GPS_C = 0x01; - proto_item *ti, *pi; - proto_tree *tf; - guint8 data, value; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_lcs_capability); - - data = tvb_get_guint8(bi->tvb, bi->offset); - - value = get_masked_guint8(data, MASK_OTD_A); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_OTD_A); - proto_item_append_text(pi, "OTD-A: MS Assisted E-OTD%s supported", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_OTD_B); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_OTD_B); - proto_item_append_text(pi, "OTD-B: MS Based E-OTD%s supported", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_GPS_A); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_GPS_A); - proto_item_append_text(pi, "GPS-A: MS Assisted GPS%s supported", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_GPS_B); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_GPS_B); - proto_item_append_text(pi, "GPS-B: MS Based GPS%s supported", - value == 0 ? " not" : ""); - - value = get_masked_guint8(data, MASK_GPS_C); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_GPS_C); - proto_item_append_text(pi, "GPS-C: Conventional GPS%s supported", - value == 0 ? " not" : ""); - - bi->offset++; -} - -static void -decode_iei_rrlp_flags(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 MASK_FLAG1 = 0x01; - proto_item *ti; - guint8 value; - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - value = tvb_get_masked_guint8(bi->tvb, bi->offset, MASK_FLAG1); - proto_item_append_text(ti, ": Flag1:%s Position Command (BSS to SGSN) or final response (SGSN to BSS) (%u)", - value == 0 ? " Not a" : "", value); - } - bi->offset++; -} - -static void /* [7] 11.3.61 RIM Application Identity */ -decode_iei_rim_application_identity(bssgp_ie_t *ie _U_, build_info_t *bi, int ie_start_offset _U_) { - proto_item *ti; - - if (!bi->bssgp_tree) { - bi->offset += 8; - return; - } - - ti = proto_tree_add_item(bi->bssgp_tree, hf_bssgp_rim_app_id, - bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN); - - bi->offset++; - -} - -#if 0 -static void -decode_ran_information_common(build_info_t *bi, proto_tree *parent_tree) { - proto_tree *tf; - proto_item *ti; - char *rai_ci; - guint8 num_rai_cis, i; - - ti = proto_tree_add_text(parent_tree, bi->tvb, bi->offset, 8, - "RAI + CI for Source Cell"); - tf = proto_item_add_subtree(ti, ett_bssgp_rai_ci); - - rai_ci = decode_rai_ci(bi, tf); - proto_item_append_text(ti, ": %s", rai_ci); - - num_rai_cis = tvb_get_guint8(bi->tvb, bi->offset); - proto_tree_add_text(tf, bi->tvb, bi->offset, 1, - "%u ""RAI+CI for Destination Cell"" follow%s", - num_rai_cis, (num_rai_cis == 0) ? "" : "s"); - bi->offset++; - - for (i = 0; i < num_rai_cis; i++) { - ti = proto_tree_add_text(parent_tree, bi->tvb, bi->offset, 8, - """RAI + CI for Destination Cell"" (%u)", i + 1); - tf = proto_item_add_subtree(ti, ett_bssgp_rai_ci); - rai_ci = decode_rai_ci(bi, tf); - proto_item_append_text(ti, ": %s", rai_ci); - } -} -#endif - -/* - * 11.3.77 RIM Routing Information - */ - -static void -decode_iei_rim_routing_information(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - proto_tree *tf; - guint8 data; - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_rim_routing_information); - - proto_tree_add_item(tf, hf_bssgp_ra_discriminator, - bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN); - - data = tvb_get_guint8(bi->tvb, bi->offset); - - bi->offset += 1; - - decode_rai(bi, tf); - - proto_tree_add_item(tf, hf_bssgp_ci, - bi->tvb, bi->offset, 2, ENC_BIG_ENDIAN); - bi->offset += 2; - - } else { - bi->offset += ie->value_length; - } - -} - -static void /* [7] 11.62a.1 */ -decode_iei_ran_container_unit(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - proto_tree *tf; - - if (!bi->bssgp_tree) { - bi->offset += 8; - return; - } - - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_ran_information_request_container_unit); -} - -static void -decode_iei_application_error(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - proto_tree *tf; - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_ran_information_container_unit); - - proto_tree_add_item(tf, hf_bssgp_iei_nacc_cause, bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN); - proto_tree_add_text(tf, bi->tvb, bi->offset, tvb_length(bi->tvb) - bi->offset , "Erroneous Application Container including IEI and LI"); - - } else { - bi->offset += ie->value_length; - } -} - -/* - * 11.3.63.1.1 RAN-INFORMATION-REQUEST Application Container for the NACC Application - */ -static void -decode_iei_ran_information_request_application_container(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - proto_tree *tf; - char *rai_ci; - - if (bi->bssgp_tree) { - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_ran_information_container_unit); - - /* - * Octet 3-10 Reporting Cell Identifier: - * This field is encoded as the Cell Identifier defined in sub-clause 11.3.9 - */ - rai_ci = decode_rai_ci(bi, tf); - proto_item_append_text(ti, ": %s", rai_ci); - - } else { - bi->offset += ie->value_length; - } -} -static void -decode_iei_ran_information_application_container(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - const guint8 MASK_NUMBER_OF_SI_PSI = 0xfe; - const guint8 MASK_UNIT_TYPE = 0x01; - const guint8 TYPE_SI = 0; - const guint8 TYPE_PSI = 1; - const guint8 LEN_SI = 21; - const guint8 LEN_PSI = 22; - proto_item *ti, *pi; - proto_tree *tf; - guint8 num_si_psi, type_si_psi, data, i; - - if (! bi->bssgp_tree) { - bi->offset += 8; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_ran_information_container_unit); - - /* don't work, ran_information_common read number of rai's but it is only one. - decode_ran_information_common(bi, tf); */ - decode_rai_ci(bi,tf); - - data = tvb_get_guint8(bi->tvb, bi->offset); - num_si_psi = get_masked_guint8(data, MASK_NUMBER_OF_SI_PSI); - type_si_psi = get_masked_guint8(data, MASK_UNIT_TYPE); - - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, - MASK_NUMBER_OF_SI_PSI); - proto_item_append_text(pi, "Number of SI/PSI: %u ""SI/PSI"" follow%s", - num_si_psi, - num_si_psi < 2 ? "s" : ""); - - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_UNIT_TYPE); - proto_item_append_text(pi, "Type: %s messages as specified for %s follow", - type_si_psi == TYPE_SI ? "SI" : "PSI", - type_si_psi == TYPE_SI ? "BCCH" : "PBCCH"); - - bi->offset++; - - for (i = 0; i < num_si_psi; i++) { - if (type_si_psi == TYPE_SI) { - proto_tree_add_text(tf, bi->tvb, bi->offset, LEN_SI, - " SI (%u), %u octets", i + 1, LEN_SI); - /* XXX: Not decoded yet; which section in 3GPP TS 44.018? */ - proto_tree_add_item(tf, hf_bssgp_rrc_si_msg_type, bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN); - /* TODO: - * Add decoding in packet-gsm_a.c ? Needs a new exported function "gsm_a_decode_rr_message?) - * - */ - bi->offset += LEN_SI; - } - else if (type_si_psi == TYPE_PSI) { - proto_tree_add_text(tf, bi->tvb, bi->offset, LEN_PSI, - " PSI (%u), %u octets", i + 1, LEN_PSI); - /* XXX: Not decoded yet; which section in 3GPP TS 44.060? - - System information messages: Reference - Packet System Information Type 1 11.2.18 - Packet System Information Type 2 11.2.19 - Packet System Information Type 3 11.2.20 - Packet System Information Type 3 bis 11.2.21 - Packet System Information Type 3 ter 11.2.21a - Packet System Information Type 3 quater 11.2.21b - Packet System Information Type 5 11.2.23 - Packet System Information Type 6 11.2.23a - Packet System Information Type 7 11.2.23b - Packet System Information Type 8 11.2.24 - Packet System Information Type 13 11.2.25 - Packet System Information Type 14 11.2.25a - Packet System Information Type 15 11.2.25b - Packet System Information Type 16 11.2.25c - */ - bi->offset += LEN_PSI; - } - } -} -static const value_string ran_inf_req_pdu_type_ext_vals[] = { - { 0,"RAN-INFORMATION-REQUEST/Stop PDU" }, - { 1,"RAN-INFORMATION-REQUEST/Single Report PDU" }, - { 2,"RAN-INFORMATION-REQUEST/Multiple Report PDU" }, - { 3,"Reserved" }, - { 4,"Reserved" }, - { 5,"Reserved" }, - { 6,"Reserved" }, - { 7,"Reserved" }, - { 0, NULL }, -}; - -static const value_string ran_inf_pdu_type_ext_vals[] = { - { 0,"RAN-INFORMATION/Stop PDU" }, - { 1,"RAN-INFORMATION/Single Report PDU" }, - { 2,"RAN-INFORMATION/Initial Multiple Report PDU" }, - { 3,"RAN-INFORMATION/Multiple Report PDU" }, - { 4,"RAN-INFORMATION/End PDU" }, - { 5,"Reserved" }, - { 6,"Reserved" }, - { 7,"Reserved" }, - { 0, NULL }, -}; -/* 11.3.65 RIM PDU Indications 3GPP TS 48.018 version 6.7.0 Release 6 */ -static void -decode_iei_rim_pdu_indications(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - /** const guint8 MASK_EXT = 0x0E; **/ - const guint8 MASK_ACK = 0x01; - proto_item *ti, *pi; - proto_tree *tf; - guint8 data, value; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_rim_pdu_indications); - - data = tvb_get_guint8(bi->tvb, bi->offset); - - if (bi->pdutype == BSSGP_IEI_RAN_INF_RIM_CONTAINER) { - proto_tree_add_item(tf, hf_ran_inf_pdu_type_ext, bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN); - }else{ - proto_tree_add_item(tf, hf_ran_inf_req_pdu_type_ext, bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN); - } - - value = get_masked_guint8(data, MASK_ACK); - pi = proto_tree_add_bitfield8(tf, bi->tvb, bi->offset, MASK_ACK); - proto_item_append_text(pi, "ACK: %sACK requested", - value == 0 ? "No " : ""); - bi->offset++; -} - -static void -decode_iei_number_of_container_units(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_item *ti; - guint8 value; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - value = tvb_get_guint8(bi->tvb, bi->offset); - proto_item_append_text(ti, ": %u Container Unit%s follow%s", - value + 1, - value == 0 ? "" : "s", - value > 0 ? "s" : ""); - bi->offset++; -} - -static void -decode_iei_pfc_flow_control_parameters(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_tree *tf, *tf2; - proto_item *ti, *ti2, *pi; - guint8 num_pfc, i, pfc_len; - gboolean b_pfc_included; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_pfc_flow_control_parameters); - - num_pfc = tvb_get_guint8(bi->tvb, bi->offset); - pi = proto_tree_add_text(bi->bssgp_tree, bi->tvb, bi->offset, 1, - "Number of PFCs: "); - - if (num_pfc < 12) { - proto_item_append_text(pi, "%u", num_pfc); - } - else { - proto_item_append_text(pi, "Reserved"); - return; - } - bi->offset++; - if (num_pfc == 0) return; - - pfc_len = (ie->value_length - 1) / num_pfc; - b_pfc_included = (pfc_len == 6); - - for (i = 0; i < num_pfc; i++) { - ti2 = proto_tree_add_text(tf, bi->tvb, bi->offset, pfc_len, - "PFC (%u)", i + 1); - tf2 = proto_item_add_subtree(ti2, ett_bssgp_pfc_flow_control_parameters_pfc); - - pi = proto_tree_add_text(tf2, bi->tvb, bi->offset, 1, "PFI"); - bssgp_pi_append_pfi(pi, bi->tvb, bi->offset); - bi->offset++; - - pi = proto_tree_add_text(tf2, bi->tvb, bi->offset, 2, "BMax_PFC"); - bssgp_pi_append_bucket_size(pi, bi->tvb, bi->offset); - bi->offset += 2; - - pi = proto_tree_add_text(tf2, bi->tvb, bi->offset, 2, "R_PFC"); - bssgp_pi_append_bucket_leak_rate(pi, bi->tvb, bi->offset); - bi->offset += 2; - if (b_pfc_included) { - pi = proto_tree_add_text(tf2, bi->tvb, bi->offset, 1, "B_PFC"); - bssgp_pi_append_bucket_full_ratio(pi, bi->tvb, bi->offset); - bi->offset++; - } - } -} - -static void -decode_iei_global_cn_id(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) { - proto_tree *ti; - proto_tree *tf; - guint16 value; - char *mcc_mnc; - - if (!bi->bssgp_tree) { - bi->offset += ie->value_length; - return; - } - ti = bssgp_proto_tree_add_ie(ie, bi, ie_start_offset); - tf = proto_item_add_subtree(ti, ett_bssgp_global_cn_id); - - mcc_mnc = decode_mcc_mnc(bi, tf); - proto_item_append_text(ti, ": PLMN-Id %s", mcc_mnc); - - value = tvb_get_ntohs(bi->tvb, bi->offset); - proto_tree_add_text(tf, bi->tvb, bi->offset, 2, - "CN-ID: %u", value); - proto_item_append_text(ti, ", CN-Id %u", value); - bi->offset += 2; -} - -static void -decode_ie(bssgp_ie_t *ie, build_info_t *bi) { - int org_offset = bi->offset; - - if (tvb_length_remaining(bi->tvb, bi->offset) < 1) { - /* TODO This code does not work well with omitted Optional elements - proto_tree_add_none_format(bi->bssgp_tree, NULL, bi->tvb, 0, -1, "[tvb_length_remaining] length remaining: %d", tvb_length_remaining(bi->tvb, bi->offset)); - */ - return; - } - switch (ie->format) { - case BSSGP_IE_FORMAT_TLV: - if (!check_correct_iei(ie, bi)) { -#ifdef BSSGP_DEBUG - /* TODO This code does not work well with omitted Optional elements */ - proto_tree_add_none_format(bi->bssgp_tree, NULL, bi->tvb, 0, -1, "[BSSGP_IE_FORMAT_TLV] format: %d", ie->format); -#endif - return; - } - bi->offset++; /* Account for type */ - ie->total_length = 1; - get_value_length(ie, bi); - break; - case BSSGP_IE_FORMAT_TV: - if (!check_correct_iei(ie, bi)) { -#ifdef BSSGP_DEBUG - /* TODO This code does not work well with omitted Optional elements */ - proto_tree_add_none_format(bi->bssgp_tree, NULL, bi->tvb, 0, -1, "[BSSGP_IE_FORMAT_TV] format: %d", ie->format); -#endif - return; - } - bi->offset++; /* Account for type */ - ie->value_length = ie->total_length - 1; - break; - case BSSGP_IE_FORMAT_V: - ie->value_length = ie->total_length; - break; - default: - ; - } - - switch (ie->iei) { - case BSSGP_IEI_ALIGNMENT_OCTETS: - decode_iei_alignment_octets(ie, bi, org_offset); - break; - case BSSGP_IEI_BMAX_DEFAULT_MS: - decode_bucket_size(ie, bi, org_offset); - break; - case BSSGP_IEI_BSS_AREA_INDICATION: - /* XXX: 'The recipient shall ignore the value of this octet'??? */ - decode_simple_ie(ie, bi, org_offset, "BSS Indicator", "", TRUE); - break; - case BSSGP_IEI_BUCKET_LEAK_RATE: - decode_bucket_leak_rate(ie, bi, org_offset); - break; - case BSSGP_IEI_BVCI: - decode_iei_bvci(ie, bi, org_offset); - break; - case BSSGP_IEI_BVC_BUCKET_SIZE: - decode_bucket_size(ie, bi, org_offset); - break; - case BSSGP_IEI_BVC_MEASUREMENT: - decode_queuing_delay(ie, bi, org_offset); - break; - case BSSGP_IEI_CAUSE: - decode_iei_cause(ie, bi, org_offset); - break; - case BSSGP_IEI_CELL_IDENTIFIER: - decode_iei_cell_identifier(ie, bi, org_offset); - break; - case BSSGP_IEI_CHANNEL_NEEDED: - decode_iei_channel_needed(ie, bi, org_offset); - break; - case BSSGP_IEI_DRX_PARAMETERS: - decode_iei_drx_parameters(ie, bi, org_offset); - break; - case BSSGP_IEI_EMLPP_PRIORITY: - decode_iei_emlpp_priority(ie, bi, org_offset); - break; - case BSSGP_IEI_FLUSH_ACTION: - decode_iei_flush_action(ie, bi, org_offset); - break; - case BSSGP_IEI_IMSI: - decode_mobile_identity(ie, bi, org_offset); - break; - case BSSGP_IEI_LLC_PDU: - bssgp_proto_handoff(ie, bi, org_offset, llc_handle); - break; - case BSSGP_IEI_LLC_FRAMES_DISCARDED: - decode_iei_llc_frames_discarded(ie, bi, org_offset); - break; - case BSSGP_IEI_LOCATION_AREA: - decode_iei_location_area(ie, bi, org_offset); - break; - case BSSGP_IEI_MOBILE_ID: - decode_mobile_identity(ie, bi, org_offset); - break; - case BSSGP_IEI_MS_BUCKET_SIZE: - decode_bucket_size(ie, bi, org_offset); - break; - case BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY: - decode_iei_ms_radio_access_capability(ie, bi, org_offset); - break; - case BSSGP_IEI_OMC_ID: - decode_iei_omc_id(ie, bi, org_offset); - break; - case BSSGP_IEI_PDU_IN_ERROR: - decode_iei_pdu_in_error(ie, bi, org_offset); - break; - case BSSGP_IEI_PDU_LIFETIME: - decode_queuing_delay(ie, bi, org_offset); - break; - case BSSGP_IEI_PRIORITY: - decode_iei_priority(ie, bi, org_offset); - break; - case BSSGP_IEI_QOS_PROFILE: - decode_iei_qos_profile(ie, bi, org_offset); - break; - case BSSGP_IEI_RADIO_CAUSE: - decode_iei_radio_cause(ie, bi, org_offset); - break; - case BSSGP_IEI_RA_CAP_UPD_CAUSE: - decode_iei_ra_cap_upd_cause(ie, bi, org_offset); - break; - case BSSGP_IEI_ROUTING_AREA: - decode_iei_routing_area(ie, bi, org_offset); - break; - case BSSGP_IEI_R_DEFAULT_MS: - decode_bucket_leak_rate(ie, bi, org_offset); - break; - case BSSGP_IEI_SUSPEND_REFERENCE_NUMBER: - decode_simple_ie(ie, bi, org_offset, "", "", TRUE); - break; - case BSSGP_IEI_TAG: - decode_simple_ie(ie, bi, org_offset, "", "", TRUE); - break; - case BSSGP_IEI_TLLI: - decode_iei_tlli(ie, bi, org_offset); - break; - case BSSGP_IEI_TMSI: - decode_iei_tmsi(ie, bi, org_offset); - break; - case BSSGP_IEI_TRACE_REFERENCE: - decode_simple_ie(ie, bi, org_offset, "", "", TRUE); - break; - case BSSGP_IEI_TRACE_TYPE: - /* XXX: Coding unknown (Specification withdrawn) 3GPP TS 32.008 */ - decode_simple_ie(ie, bi, org_offset, "", "", TRUE); - break; - case BSSGP_IEI_TRANSACTION_ID: - decode_simple_ie(ie, bi, org_offset, "", "", TRUE); - break; - case BSSGP_IEI_TRIGGER_ID: - decode_iei_trigger_id(ie, bi, org_offset); - break; - case BSSGP_IEI_NUMBER_OF_OCTETS_AFFECTED: - decode_simple_ie(ie, bi, org_offset, "", "", TRUE); - break; - case BSSGP_IEI_LSA_IDENTIFIER_LIST: - decode_iei_lsa_identifier_list(ie, bi, org_offset); - break; - case BSSGP_IEI_LSA_INFORMATION: - decode_iei_lsa_information(ie, bi, org_offset); - break; - case BSSGP_IEI_PFI: - decode_pfi(ie, bi, org_offset); - break; - case BSSGP_IEI_GPRS_TIMER: - decode_iei_gprs_timer(ie, bi, org_offset); - break; - case BSSGP_IEI_ABQP: - decode_iei_abqp(ie, bi, org_offset); - break; - case BSSGP_IEI_FEATURE_BITMAP: - decode_iei_feature_bitmap(ie, bi, org_offset); - break; - case BSSGP_IEI_BUCKET_FULL_RATIO: - decode_iei_bucket_full_ratio(ie, bi, org_offset); - break; - case BSSGP_IEI_SERVICE_UTRAN_CCO: - decode_iei_service_utran_cco(ie, bi, org_offset); - break; - case BSSGP_IEI_NSEI: - decode_iei_nsei(ie, bi, org_offset); - break; - case BSSGP_IEI_RRLP_APDU: - bssgp_proto_handoff(ie, bi, org_offset, rrlp_handle); - break; - case BSSGP_IEI_LCS_QOS: - decode_iei_lcs_qos(ie, bi, org_offset); - break; - case BSSGP_IEI_LCS_CLIENT_TYPE: - decode_iei_lcs_client_type(ie, bi, org_offset); - break; - case BSSGP_IEI_REQUESTED_GPS_ASSISTANCE_DATA: - decode_iei_requested_gps_assistance_data(ie, bi, org_offset); - break; - case BSSGP_IEI_LOCATION_TYPE: - decode_iei_location_type(ie, bi, org_offset); - break; - case BSSGP_IEI_LOCATION_ESTIMATE: - decode_iei_location_estimate(ie, bi, org_offset); - break; - case BSSGP_IEI_POSITIONING_DATA: - decode_iei_positioning_data(ie, bi, org_offset); - break; - case BSSGP_IEI_DECIPHERING_KEYS: - decode_iei_deciphering_keys(ie, bi, org_offset); - break; - case BSSGP_IEI_LCS_PRIORITY: - decode_iei_lcs_priority(ie, bi, org_offset); - break; - case BSSGP_IEI_LCS_CAUSE: - decode_iei_lcs_cause(ie, bi, org_offset); - break; - case BSSGP_IEI_LCS_CAPABILITY: - decode_iei_lcs_capability(ie, bi, org_offset); - break; - case BSSGP_IEI_RRLP_FLAGS: - decode_iei_rrlp_flags(ie, bi, org_offset); - break; - case BSSGP_IEI_RIM_ROUTING_INFORMATION: - decode_iei_rim_routing_information(ie, bi, org_offset); - break; - case BSSGP_IEI_RIM_APP_ID: - decode_iei_rim_application_identity(ie, bi, org_offset); - break; - case BSSGP_IEI_RIM_SEQUENCE_NUMBER: - decode_simple_ie(ie, bi, org_offset, "", "", TRUE); - break; - case BSSGP_IEI_RIM_PROTOCOL_VERSION: - decode_simple_ie(ie, bi, org_offset, "", "", TRUE); - break; - - case BSSGP_IEI_RAN_INF_REQUEST_APP_CONTAINER: - decode_iei_ran_information_request_application_container(ie, bi, org_offset); - break; - case BSSGP_IEI_RAN_INF_APP_CONTAINER: - decode_iei_ran_information_application_container(ie, bi, org_offset); - break; - - case BSSGP_IEI_RAN_INF_REQUEST_RIM_CONTAINER: - decode_iei_ran_container_unit(ie, bi, org_offset); - break; - case BSSGP_IEI_RAN_INF_RIM_CONTAINER: - decode_iei_ran_container_unit(ie, bi, org_offset); - break; - case BSSGP_IEI_RAN_INF_APP_ERROR_RIM_CONTAINER: - decode_iei_ran_container_unit(ie, bi, org_offset); - break; - case BSSGP_IEI_RAN_INF_ACK_RIM_CONTAINER: - decode_iei_ran_container_unit(ie, bi, org_offset); - break; - case BSSGP_IEI_RAN_INF_ERROR_RIM_CONTAINER: - decode_iei_ran_container_unit(ie, bi, org_offset); - break; - - case BSSGP_IEI_APPLICATION_ERROR_CONTAINER: - decode_iei_application_error(ie, bi, org_offset); - break; - - - case BSSGP_IEI_RIM_PDU_INDICATIONS: - decode_iei_rim_pdu_indications(ie, bi, org_offset); - break; - case BSSGP_IEI_NUMBER_OF_CONTAINER_UNITS: - decode_iei_number_of_container_units(ie, bi, org_offset); - break; - case BSSGP_IEI_PFC_FLOW_CONTROL_PARAMETERS: - decode_iei_pfc_flow_control_parameters(ie, bi, org_offset); - break; - case BSSGP_IEI_GLOBAL_CN_ID: - decode_iei_global_cn_id(ie, bi, org_offset); - break; - default: - ; - } -} - -static void -decode_pdu_general(bssgp_ie_t *ies, int num_ies, build_info_t *bi) { - int i; - for (i = 0; i < num_ies; i++) { - decode_ie(&ies[i], bi); - } -} - -static void -decode_pdu_dl_unitdata(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, "TLLI (current)", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_V, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_QOS_PROFILE, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_V, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_PDU_LIFETIME, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4}, - - { BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN}, - - { BSSGP_IEI_PRIORITY, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3}, - - { BSSGP_IEI_DRX_PARAMETERS, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4}, - - { BSSGP_IEI_IMSI, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN}, - - { BSSGP_IEI_TLLI, "TLLI (old)", - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6}, - - { BSSGP_IEI_PFI, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3}, - - { BSSGP_IEI_LSA_INFORMATION, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN}, - - { BSSGP_IEI_SERVICE_UTRAN_CCO, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3}, - - { BSSGP_IEI_ALIGNMENT_OCTETS, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN}, - - { BSSGP_IEI_LLC_PDU, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN}, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 13, bi); -} - -static void -decode_pdu_ul_unitdata(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_V, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_QOS_PROFILE, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_V, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_CELL_IDENTIFIER, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 }, - - { BSSGP_IEI_PFI, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_LSA_IDENTIFIER_LIST, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_ALIGNMENT_OCTETS, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_LLC_PDU, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 7, bi); -} - -static void -decode_pdu_ra_capability(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN}, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 2, bi); -} - -static void -decode_pdu_ptm_unitdata(build_info_t *bi) { - proto_tree_add_text(bi->bssgp_tree, bi->tvb, bi->offset, -1, - "This shall be developed in GPRS phase 2"); -} - -static void -decode_pdu_paging_ps(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_IMSI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_DRX_PARAMETERS, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_BVCI, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_LOCATION_AREA, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 7 }, - - { BSSGP_IEI_ROUTING_AREA, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 }, - - { BSSGP_IEI_BSS_AREA_INDICATION, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_PFI, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_ABQP, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_QOS_PROFILE, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 5 }, - - { BSSGP_IEI_TMSI, "P-TMSI", - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 10, bi); -} - -static void -decode_pdu_paging_cs(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_IMSI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_DRX_PARAMETERS, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_BVCI, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_LOCATION_AREA, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 7 }, - - { BSSGP_IEI_ROUTING_AREA, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 }, - - { BSSGP_IEI_BSS_AREA_INDICATION, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_CHANNEL_NEEDED, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_EMLPP_PRIORITY, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_TMSI, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_GLOBAL_CN_ID, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 7 }, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 11, bi); -} - -static void -decode_pdu_ra_capability_update(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_TAG, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 2, bi); -} - -static void -decode_pdu_ra_capability_update_ack(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_TAG, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_IMSI, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_RA_CAP_UPD_CAUSE, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN}, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 5, bi); -} - -static void -decode_pdu_radio_status(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_TMSI, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_IMSI, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_RADIO_CAUSE, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 4, bi); -} - -static void -decode_pdu_suspend(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_ROUTING_AREA, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 2, bi); -} - -void -decode_pdu_suspend_ack(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_ROUTING_AREA, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 }, - - { BSSGP_IEI_SUSPEND_REFERENCE_NUMBER, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 3, bi); -} - -static void -decode_pdu_suspend_nack(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_ROUTING_AREA, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 }, - - { BSSGP_IEI_CAUSE, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 3, bi); -} - -static void -decode_pdu_resume(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_ROUTING_AREA, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 }, - - { BSSGP_IEI_SUSPEND_REFERENCE_NUMBER, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 3, bi); -} - -static void -decode_pdu_resume_ack(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_ROUTING_AREA, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 }, - - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 2, bi); -} - -static void -decode_pdu_resume_nack(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_ROUTING_AREA, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 8 }, - - { BSSGP_IEI_CAUSE, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 3, bi); -} - -static void -decode_pdu_bvc_block(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_BVCI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_CAUSE, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 2, bi); -} - -static void -decode_pdu_bvc_block_ack(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_BVCI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4}, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 1, bi); -} - -static void -decode_pdu_bvc_reset(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_BVCI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_CAUSE, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_CELL_IDENTIFIER, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 }, - - { BSSGP_IEI_FEATURE_BITMAP, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = TRUE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 4, bi); -} - -static void -decode_pdu_bvc_reset_ack(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_BVCI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_CELL_IDENTIFIER, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 }, - - { BSSGP_IEI_FEATURE_BITMAP, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = TRUE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 3, bi); -} - -static void -decode_pdu_bvc_unblock(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_BVCI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 1, bi); -} - -static void -decode_pdu_bvc_unblock_ack(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_BVCI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 1, bi); -} - -static void -decode_pdu_flow_control_bvc(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TAG, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_BVC_BUCKET_SIZE, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_BUCKET_LEAK_RATE, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_BMAX_DEFAULT_MS, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_R_DEFAULT_MS, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_BUCKET_FULL_RATIO, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_BVC_MEASUREMENT, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 7, bi); -} - -static void -decode_pdu_flow_control_bvc_ack(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TAG, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 1, bi); -} - -static void -decode_pdu_flow_control_ms(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_TAG, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_MS_BUCKET_SIZE, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_BUCKET_LEAK_RATE, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_BUCKET_FULL_RATIO, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 5, bi); -} - -static void -decode_pdu_flow_control_ms_ack(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_TAG, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 2, bi); -} - -static void -decode_pdu_flush_ll(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_BVCI, "BVCI (old)", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_BVCI, "BVCI (new)", - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_NSEI, "NSEI (new)", - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 4, bi); -} - -static void -decode_pdu_flush_ll_ack(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_FLUSH_ACTION, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_BVCI, "BVCI (new)", - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_NUMBER_OF_OCTETS_AFFECTED, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 5 }, - - { BSSGP_IEI_NSEI, "NSEI (new)", - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 5, bi); -} - -static void -decode_pdu_llc_discarded(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_LLC_FRAMES_DISCARDED, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_BVCI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_NUMBER_OF_OCTETS_AFFECTED, "Number of octets deleted", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 5 }, - - { BSSGP_IEI_PFI, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 5, bi); -} - -static void -decode_pdu_flow_control_pfc(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_TAG, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_MS_BUCKET_SIZE, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_BUCKET_LEAK_RATE, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_BUCKET_FULL_RATIO, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_PFC_FLOW_CONTROL_PARAMETERS, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 6, bi); -} - -static void -decode_pdu_flow_control_pfc_ack(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_TAG, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 2, bi); -} - -static void -decode_pdu_sgsn_invoke_trace(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TRACE_TYPE, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_TRACE_REFERENCE, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_TRIGGER_ID, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_MOBILE_ID, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_OMC_ID, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_TRANSACTION_ID, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 6, bi); -} - -static void -decode_pdu_status(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_CAUSE, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_BVCI, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_PDU_IN_ERROR, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - }; - bi->dl_data = TRUE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 3, bi); -} - -static void -decode_pdu_download_bss_pfc(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_PFI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 2, bi); -} - -/* 10.4.17 CREATE-BSS-PFC */ -static void -decode_pdu_create_bss_pfc(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_IMSI, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_PFI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_GPRS_TIMER, "PFT", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_ABQP, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_SERVICE_UTRAN_CCO, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_MS_RADIO_ACCESS_CAPABILITY, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_PRIORITY, "Allocation/Retention Priority", - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_GPRS_TIMER, "T10", - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - /* Inter RAT Handover Info 11.3.94 3GPP TS 48.018 version 6.11.0 Release 6 */ - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 9, bi); -} - -static void -decode_pdu_create_bss_pfc_ack(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_PFI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_ABQP, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_CAUSE, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 4, bi); -} - -static void -decode_pdu_create_bss_pfc_nack(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_PFI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_CAUSE, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 3, bi); -} - -static void -decode_pdu_modify_bss_pfc(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_PFI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_ABQP, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 3, bi); -} - -static void -decode_pdu_modify_bss_pfc_ack(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_PFI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_GPRS_TIMER, "PFT", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_ABQP, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 4, bi); -} - -static void -decode_pdu_delete_bss_pfc(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_PFI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 2, bi); -} - -static void -decode_pdu_delete_bss_pfc_ack(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_PFI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 2, bi); -} -/* - * 10.4.26 DELETE-BSS-PFC-REQ - */ -static void -decode_pdu_delete_bss_pfc_req(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_PFI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_CAUSE, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 3, bi); -} - -static void -decode_pdu_perform_location_request(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_IMSI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_DRX_PARAMETERS, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_BVCI, "BVCI (PCU-PTP)", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_NSEI, "NSEI (PCU-PTP)", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_LOCATION_TYPE, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_CELL_IDENTIFIER, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 }, - - { BSSGP_IEI_LCS_CAPABILITY, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_LCS_PRIORITY, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_LCS_QOS, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_LCS_CLIENT_TYPE, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_REQUESTED_GPS_ASSISTANCE_DATA, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 12, bi); -} - -static void -decode_pdu_perform_location_response(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_BVCI, "BVCI (PCU-PTP)", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_LOCATION_ESTIMATE, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_POSITIONING_DATA, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_DECIPHERING_KEYS, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_LCS_CAUSE, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 6, bi); -} - -static void -decode_pdu_perform_location_abort(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_BVCI, "BVCI (PCU-PTP)", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_LCS_CAUSE, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 3, bi); -} - -static void -decode_pdu_position_command(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_BVCI, "BVCI (PCU-PTP)", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_RRLP_FLAGS, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_RRLP_APDU, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - }; - bi->dl_data = FALSE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 4, bi); -} - -static void -decode_pdu_position_response(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_TLLI, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_BVCI, "BVCI (PCU-PTP)", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - { BSSGP_IEI_RRLP_FLAGS, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_RRLP_APDU, NULL, - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - { BSSGP_IEI_LCS_CAUSE, NULL, - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - }; - bi->dl_data = TRUE; - bi->ul_data = FALSE; - - decode_pdu_general(ies, 5, bi); -} - - -static void -decode_pdu_ran_information(build_info_t *bi) { - bssgp_ie_t ies[] = { - - { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Destination Cell Identifier", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 }, - - { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Source Cell Identifier", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 }, - - { BSSGP_IEI_RAN_INF_RIM_CONTAINER, "RAN-INFORMATION RIM Container", - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 2 }, - - { BSSGP_IEI_RIM_APP_ID, "Application Identity", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_RIM_SEQUENCE_NUMBER, "Sequence Number", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_RIM_PDU_INDICATIONS, "PDU Indications", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_RIM_PROTOCOL_VERSION, "Protocol Version", - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_RAN_INF_APP_CONTAINER, "RAN-INFORMATION RIM Container", - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - }; - - bi->dl_data = TRUE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 8, bi); -} - -static void -decode_pdu_ran_information_request(build_info_t *bi) { - - bssgp_ie_t ies[] = { - - { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Destination Cell Identifier", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 }, - - { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Source Cell Identifier", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 }, - - { BSSGP_IEI_RAN_INF_REQUEST_RIM_CONTAINER, "RAN-INFORMATION-REQUEST RIM Container", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 2 }, - - { BSSGP_IEI_RIM_APP_ID, "Application Identity", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_RIM_SEQUENCE_NUMBER, "Sequence Number", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_RIM_PDU_INDICATIONS, "PDU Indications", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_RIM_PROTOCOL_VERSION, "Protocol Version", - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_RAN_INF_REQUEST_APP_CONTAINER, "RAN-INFORMATION-REQUEST Application Container", - BSSGP_IE_PRESENCE_O, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - }; - - bi->dl_data = TRUE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 8, bi); - -} - -static void -decode_pdu_ran_information_ack(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Destination Cell Identifier", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 }, - - { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Source Cell Identifier", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 }, - - { BSSGP_IEI_RAN_INF_REQUEST_RIM_CONTAINER, "RAN-INFORMATION-ACK RIM Container", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 2 }, - - { BSSGP_IEI_RIM_APP_ID, "Application Identity", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_RIM_SEQUENCE_NUMBER, "Sequence Number", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_RIM_PROTOCOL_VERSION, "Protocol Version", - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 4 }, - - }; - bi->dl_data = TRUE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 6, bi); -} - -static void -decode_pdu_ran_information_error(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Destination Cell Identifier", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 }, - - { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Source Cell Identifier", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 }, - - { BSSGP_IEI_RAN_INF_REQUEST_RIM_CONTAINER, "RAN-INFORMATION-ERROR RIM Container", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 2 }, - - { BSSGP_IEI_RIM_APP_ID, "Application Identity", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_CAUSE, "RIM Cause", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_RIM_PROTOCOL_VERSION, "Protocol Version", - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_PDU_IN_ERROR, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - }; - bi->dl_data = TRUE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 7, bi); -} - -static void -decode_pdu_ran_information_application_error(build_info_t *bi) { - bssgp_ie_t ies[] = { - { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Destination Cell Identifier", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 }, - - { BSSGP_IEI_RIM_ROUTING_INFORMATION, "Source Cell Identifier", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 10 }, - - { BSSGP_IEI_RAN_INF_REQUEST_RIM_CONTAINER, "RAN-INFORMATION-APPLICATION RIM Container", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 2 }, - - { BSSGP_IEI_RIM_APP_ID, "Application Identity", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - /* pdu indication, I hope RIM_PDU_INDICATIONS decode it right, it use the same IEI so it should... */ - { BSSGP_IEI_RIM_PDU_INDICATIONS, "PDU Indications", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_RIM_SEQUENCE_NUMBER, "Sequence Number", - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 6 }, - - { BSSGP_IEI_RIM_PROTOCOL_VERSION, "Protocol Version", - BSSGP_IE_PRESENCE_C, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, 3 }, - - { BSSGP_IEI_APPLICATION_ERROR_CONTAINER, NULL, - BSSGP_IE_PRESENCE_M, BSSGP_IE_FORMAT_TLV, BSSGP_UNKNOWN, BSSGP_UNKNOWN }, - - }; - bi->dl_data = TRUE; - bi->ul_data = TRUE; - - decode_pdu_general(ies, 8, bi); -} - - -static void -decode_pdu(build_info_t *bi) { - - switch (bi->pdutype) { - case BSSGP_PDU_DL_UNITDATA: - decode_pdu_dl_unitdata(bi); - break; - case BSSGP_PDU_UL_UNITDATA: - decode_pdu_ul_unitdata(bi); - break; - case BSSGP_PDU_RA_CAPABILITY: - decode_pdu_ra_capability(bi); - break; - case BSSGP_PDU_PTM_UNITDATA: - decode_pdu_ptm_unitdata(bi); - break; - case BSSGP_PDU_PAGING_PS: - decode_pdu_paging_ps(bi); - break; - case BSSGP_PDU_PAGING_CS: - decode_pdu_paging_cs(bi); - break; - case BSSGP_PDU_RA_CAPABILITY_UPDATE: - decode_pdu_ra_capability_update(bi); - break; - case BSSGP_PDU_RA_CAPABILITY_UPDATE_ACK: - decode_pdu_ra_capability_update_ack(bi); - break; - case BSSGP_PDU_RADIO_STATUS: - decode_pdu_radio_status(bi); - break; - case BSSGP_PDU_SUSPEND: - decode_pdu_suspend(bi); - break; - case BSSGP_PDU_SUSPEND_ACK: - decode_pdu_suspend_ack(bi); - break; - case BSSGP_PDU_SUSPEND_NACK: - decode_pdu_suspend_nack(bi); - break; - case BSSGP_PDU_RESUME: - decode_pdu_resume(bi); - break; - case BSSGP_PDU_RESUME_ACK: - decode_pdu_resume_ack(bi); - break; - case BSSGP_PDU_RESUME_NACK: - decode_pdu_resume_nack(bi); - break; - case BSSGP_PDU_BVC_BLOCK: - decode_pdu_bvc_block(bi); - break; - case BSSGP_PDU_BVC_BLOCK_ACK: - decode_pdu_bvc_block_ack(bi); - break; - case BSSGP_PDU_BVC_RESET: - decode_pdu_bvc_reset(bi); - break; - case BSSGP_PDU_BVC_RESET_ACK: - decode_pdu_bvc_reset_ack(bi); - break; - case BSSGP_PDU_BVC_UNBLOCK: - decode_pdu_bvc_unblock(bi); - break; - case BSSGP_PDU_BVC_UNBLOCK_ACK: - decode_pdu_bvc_unblock_ack(bi); - break; - case BSSGP_PDU_FLOW_CONTROL_BVC: - decode_pdu_flow_control_bvc(bi); - break; - case BSSGP_PDU_FLOW_CONTROL_BVC_ACK: - decode_pdu_flow_control_bvc_ack(bi); - break; - case BSSGP_PDU_FLOW_CONTROL_MS: - decode_pdu_flow_control_ms(bi); - break; - case BSSGP_PDU_FLOW_CONTROL_MS_ACK: - decode_pdu_flow_control_ms_ack(bi); - break; - case BSSGP_PDU_FLUSH_LL: - decode_pdu_flush_ll(bi); - break; - case BSSGP_PDU_FLUSH_LL_ACK: - decode_pdu_flush_ll_ack(bi); - break; - case BSSGP_PDU_LLC_DISCARDED: - decode_pdu_llc_discarded(bi); - break; - case BSSGP_PDU_FLOW_CONTROL_PFC: - decode_pdu_flow_control_pfc(bi); - break; - case BSSGP_PDU_FLOW_CONTROL_PFC_ACK: - decode_pdu_flow_control_pfc_ack(bi); - break; - case BSSGP_PDU_SGSN_INVOKE_TRACE: - decode_pdu_sgsn_invoke_trace(bi); - break; - case BSSGP_PDU_STATUS: - decode_pdu_status(bi); - break; - case BSSGP_PDU_DOWNLOAD_BSS_PFC: - decode_pdu_download_bss_pfc(bi); - break; - case BSSGP_PDU_CREATE_BSS_PFC: - decode_pdu_create_bss_pfc(bi); - break; - case BSSGP_PDU_CREATE_BSS_PFC_ACK: - decode_pdu_create_bss_pfc_ack(bi); - break; - case BSSGP_PDU_CREATE_BSS_PFC_NACK: - decode_pdu_create_bss_pfc_nack(bi); - break; - case BSSGP_PDU_MODIFY_BSS_PFC: - decode_pdu_modify_bss_pfc(bi); - break; - case BSSGP_PDU_MODIFY_BSS_PFC_ACK: - decode_pdu_modify_bss_pfc_ack(bi); - break; - case BSSGP_PDU_DELETE_BSS_PFC: - decode_pdu_delete_bss_pfc(bi); - break; - case BSSGP_PDU_DELETE_BSS_PFC_ACK: - decode_pdu_delete_bss_pfc_ack(bi); - break; - case BSSGP_PDU_DELETE_BSS_PFC_REQ: - decode_pdu_delete_bss_pfc_req(bi); - break; -#if 0 - case BSSGP_PDU_PS_HANDOVER_REQUIRED: - decode_pdu_ps_handover_required(bi); - break; - case BSSGP_PDU_PS_HANDOVER_REQUIRED_ACK: - case BSSGP_PDU_PS_HANDOVER_REQUIRED_NACK: - case BSSGP_PDU_PS_HANDOVER_REQUEST: - case BSSGP_PDU_PS_HANDOVER_REQUEST_ACK: - case BSSGP_PDU_PS_HANDOVER_REQUEST_NACK: - break; -#endif - case BSSGP_PDU_PERFORM_LOCATION_REQUEST: - decode_pdu_perform_location_request(bi); - break; - case BSSGP_PDU_PERFORM_LOCATION_RESPONSE: - decode_pdu_perform_location_response(bi); - break; - case BSSGP_PDU_PERFORM_LOCATION_ABORT: - decode_pdu_perform_location_abort(bi); - break; - case BSSGP_PDU_POSITION_COMMAND: - decode_pdu_position_command(bi); - break; - case BSSGP_PDU_POSITION_RESPONSE: - decode_pdu_position_response(bi); - break; - case BSSGP_PDU_RAN_INFORMATION: - decode_pdu_ran_information(bi); - break; - case BSSGP_PDU_RAN_INFORMATION_REQUEST: - decode_pdu_ran_information_request(bi); - break; - case BSSGP_PDU_RAN_INFORMATION_ACK: - decode_pdu_ran_information_ack(bi); - break; - case BSSGP_PDU_RAN_INFORMATION_APP_ERROR: - decode_pdu_ran_information_application_error(bi); - break; - case BSSGP_PDU_RAN_INFORMATION_ERROR: - decode_pdu_ran_information_error(bi); - break; - default: - ; - } -} /* * 11.3 Information Element Identifier (IEI) */ @@ -7913,21 +2217,27 @@ de_bssgp_pfc_flow_ctrl(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint le "PFC (%u)", i + 1); pfc_tree = proto_item_add_subtree(ti2, ett_bssgp_pfc_flow_control_parameters_pfc); - pi = proto_tree_add_text(pfc_tree, tvb, curr_offset, 1, "PFI"); - bssgp_pi_append_pfi(pi, tvb, curr_offset); + /* PFI: Packet Flow Identifier. + * Coded as the value part of the Packet Flow Identifier information element in + * 3GPP TS 24.008, not including 3GPP TS 24.008 IEI + */ + de_sm_pflow_id(tvb, pfc_tree, curr_offset, 1, NULL, 0); curr_offset++; - pi = proto_tree_add_text(pfc_tree, tvb, curr_offset, 2, "BMax_PFC"); - bssgp_pi_append_bucket_size(pi, tvb, curr_offset); + /* Bmax_PFC: Bucket size of the PFC. Coded like the value part of BVC Bucket Size, see sub-clause 11.3.5. */ + proto_tree_add_item(tree, hf_bssgp_bmax_pfc, tvb, curr_offset, 2, ENC_BIG_ENDIAN); curr_offset += 2; - pi = proto_tree_add_text(pfc_tree, tvb, curr_offset, 2, "R_PFC"); - bssgp_pi_append_bucket_leak_rate(pi, tvb, curr_offset); + /* R_PFC: Bucket Leak Rate of the PFC. Coded as the value part of Bucket Leak Rate (R), see sub-clause 11.3.4. */ + proto_tree_add_item(tree, hf_bssgp_r_pfc, tvb, curr_offset, 2, ENC_BIG_ENDIAN); curr_offset += 2; if (b_pfc_included) { - pi = proto_tree_add_text(pfc_tree, tvb, curr_offset, 1, "B_PFC"); - bssgp_pi_append_bucket_full_ratio(pi, tvb, curr_offset); + /* B_PFC: Bucket Full Ratio of the PFC. This field is only present if the Current Bucket Level (CBL) feature is + * negotiated. Otherwise, the flow control parameters for the next PFC, if any, are provided instead. This field if coded as + * the value part of the Bucket Full Ratio, see sub-clause 11.3.46. + */ + proto_tree_add_item(tree, hf_bssgp_b_pfc, tvb, curr_offset, 1, ENC_BIG_ENDIAN); curr_offset++; } } @@ -8098,8 +2408,7 @@ de_bssgp_pfcs_to_be_set_up_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, "PFC (%u)", i + 1); pfc_tree = proto_item_add_subtree(ti2, ett_bssgp_pfcs_to_be_set_up_list); - pi = proto_tree_add_text(pfc_tree, tvb, curr_offset, 1, "PFI"); - bssgp_pi_append_pfi(pi, tvb, curr_offset); + de_sm_pflow_id(tvb, pfc_tree, curr_offset, 1, NULL, 0); curr_offset++; /* PFT: Packet Flow Timer. Coded as the GPRS Timer information element, @@ -8176,8 +2485,7 @@ de_bssgp_list_of_setup_pfcs(tvbuff_t *tvb, proto_tree *tree, guint32 offset, gui "PFC (%u)", i + 1); pfc_tree = proto_item_add_subtree(ti2, ett_bssgp_list_of_setup_pfcs); - pi = proto_tree_add_text(pfc_tree, tvb, curr_offset, 1, "PFI"); - bssgp_pi_append_pfi(pi, tvb, curr_offset); + de_sm_pflow_id(tvb, pfc_tree, curr_offset, 1, NULL, 0); curr_offset++; } @@ -8498,8 +2806,7 @@ de_bssgp_active_pfcs_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint ti2 = proto_tree_add_text(tree, tvb, curr_offset, 1, "PFC (%u)", i + 1); pfc_tree = proto_item_add_subtree(ti2, ett_bssgp_pfc_flow_control_parameters_pfc); - pi = proto_tree_add_text(pfc_tree, tvb, curr_offset, 1, "PFI"); - bssgp_pi_append_pfi(pi, tvb, curr_offset); + de_sm_pflow_id(tvb, pfc_tree, curr_offset, 1, NULL, 0); curr_offset++; } @@ -11443,16 +5750,15 @@ void get_bssgp_msg_params(guint8 oct, const gchar **msg_str, int *ett_tree, int static void dissect_bssgp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - build_info_t bi = { NULL, 0, NULL, NULL, NULL, FALSE, FALSE, 0 }; proto_item *ti; proto_tree *bssgp_tree = NULL; int offset = 0; guint32 len; const gchar *msg_str = NULL; - gint ett_tree; + gint ett_tree; int hf_idx; - void (*msg_fcn)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len); + void (*msg_fcn)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len); /* Save pinfo */ gpinfo = pinfo; @@ -11460,25 +5766,15 @@ dissect_bssgp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) gparent_tree = tree; len = tvb_length(tvb); - - bi.tvb = tvb; - bi.pinfo = pinfo; - bi.parent_tree = tree; - - pinfo->current_proto = "BSSGP"; - col_set_str(pinfo->cinfo, COL_PROTOCOL, "BSSGP"); col_clear(pinfo->cinfo, COL_INFO); - bi.pdutype = tvb_get_guint8(tvb, 0); - bi.offset++; g_pdu_type = tvb_get_guint8(tvb,offset); if (tree) { ti = proto_tree_add_item(tree, proto_bssgp, tvb, 0, -1, ENC_NA); bssgp_tree = proto_item_add_subtree(ti, ett_bssgp); - bi.bssgp_tree = bssgp_tree; } /* Messge type IE*/ @@ -11489,49 +5785,33 @@ dissect_bssgp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) get_bssgp_msg_params(g_pdu_type, &msg_str, &ett_tree, &hf_idx, &msg_fcn); - col_add_str(pinfo->cinfo, COL_INFO, val_to_str(bi.pdutype, - tab_bssgp_pdu_types, - "Unknown PDU type")); - - /* PDU's with msg no lover than this value are converted to common dissection style */ - if(g_pdu_type>0x7f){ - proto_tree_add_item(bssgp_tree, hf_bssgp_msg_type, tvb, 0, 1, ENC_BIG_ENDIAN); - decode_pdu(&bi); + if(msg_str){ + col_add_fstr(pinfo->cinfo, COL_INFO, "%s", msg_str); }else{ - /* New dissection code, aligning the dissector with the other GSM/UMTS/LTE dissectors - * to make it possible to share IE dissection as IE's are shared between specs. - * old code is keept untill transition is complete. - */ - - if(msg_str){ - col_add_fstr(pinfo->cinfo, COL_INFO, "%s", msg_str); - }else{ - proto_tree_add_text(bssgp_tree, tvb, offset, 1,"Unknown message 0x%x",g_pdu_type); - return; - } + proto_tree_add_text(bssgp_tree, tvb, offset, 1,"Unknown message 0x%x",g_pdu_type); + return; + } - /* - * Add BSSGP message name - */ - proto_tree_add_item(bssgp_tree, hf_idx, tvb, offset, 1, FALSE); - offset++; + /* + * Add BSSGP message name + */ + proto_tree_add_item(bssgp_tree, hf_idx, tvb, offset, 1, FALSE); + offset++; - /* - * decode elements - */ - if (msg_fcn == NULL) - { - proto_tree_add_text(bssgp_tree, tvb, offset, len - offset, "Message Elements"); - } - else - { - /* If calling any "gsm" ie dissectors needing pinfo */ - gsm_a_dtap_pinfo = pinfo; - (*msg_fcn)(tvb, bssgp_tree, offset, len - offset); - } - }/*End new dissection */ - + /* + * decode elements + */ + if (msg_fcn == NULL) + { + proto_tree_add_text(bssgp_tree, tvb, offset, len - offset, "Message Elements"); + } + else + { + /* If calling any "gsm" ie dissectors needing pinfo */ + gsm_a_dtap_pinfo = pinfo; + (*msg_fcn)(tvb, bssgp_tree, offset, len - offset); + } } void @@ -11542,25 +5822,15 @@ proto_register_bssgp(void) static hf_register_info hf[] = { { &hf_bssgp_msg_type, - { "PDU Type", "bssgp.pdu_type", - FT_UINT8, BASE_HEX, VALS(tab_bssgp_pdu_types), 0x0, - NULL, HFILL } - }, + { "PDU Type", "bssgp.pdu_type", + FT_UINT8, BASE_HEX|BASE_EXT_STRING, &bssgp_msg_strings_ext, 0x0, + NULL, HFILL } + }, { &hf_bssgp_elem_id, { "Element ID", "bssgp.elem_id", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } }, - { &hf_bssgp_iei_nacc_cause, - { "NACC Cause", "bssgp.iei.nacc_cause", - FT_UINT8, BASE_HEX, VALS(tab_nacc_cause), 0x0, - NULL, HFILL } - }, - { &hf_bssgp_ie_type, - { "IE Type", "bssgp.ie_type", - FT_UINT8, BASE_HEX, VALS(tab_bssgp_ie_types), 0x0, - "Information element type", HFILL } - }, { &hf_bssgp_bss_area_ind, { "BSS indicator", "bssgp.bss_ind", FT_UINT8, BASE_HEX, NULL, 0x0, @@ -11581,21 +5851,26 @@ proto_register_bssgp(void) FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_bssgp_r_pfc, + { "R_PFC(x 100 or in increments as defined by the Flow Control Granularity IE)", "bssgp.r_pfc", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, { &hf_bssgp_bucket_size, { "Bmax(x 100 or in increments as defined by the Flow Control Granularity IE)", "bssgp.bucket_size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_bssgp_bmax_pfc, + { "Bmax_PFC(x 100 or in increments as defined by the Flow Control Granularity IE)", "bssgp.bmax_pfc", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, { &hf_bssgp_omc_id, { "OMC identity", "bssgp.omc_id", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, - { &hf_bssgp_tlli, - { "TLLI", "bssgp.tlli", - FT_UINT32, BASE_HEX, NULL, 0x0, - NULL, HFILL } - }, { &hf_bssgp_nsei, { "NSEI", "bssgp.nsei", FT_UINT16, BASE_HEX, NULL, 0x0, @@ -11606,32 +5881,11 @@ proto_register_bssgp(void) FT_BOOLEAN, 8, TFS(&bssgp_rrlp_flg1_vals), 0x01, NULL, HFILL } }, - - { &hf_bssgp_mcc, - { "MCC", "bssgp.mcc", - FT_UINT8, BASE_DEC|BASE_EXT_STRING, &E212_codes_ext, 0x0, - NULL, HFILL } - }, - { &hf_bssgp_mnc, - { "MNC", "bssgp.mnc", - FT_UINT8, BASE_DEC, NULL, 0x0, - NULL, HFILL } - }, - { &hf_bssgp_lac, - { "LAC", "bssgp.lac", - FT_UINT16, BASE_DEC, NULL, 0x0, - NULL, HFILL } - }, - { &hf_bssgp_rac, - { "RAC", "bssgp.rac", - FT_UINT8, BASE_DEC, NULL, 0x0, - NULL, HFILL } - }, - { &hf_bssgp_ci, - { "CI", "bssgp.ci", - FT_UINT16, BASE_HEX, NULL, 0x0, - "Cell Identity", HFILL } - }, + { &hf_bssgp_ci, + { "CI", "bssgp.ci", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Cell Identity", HFILL } + }, { &hf_bssgp_flush_action, { "Action", "bssgp.ci", FT_UINT8, BASE_DEC, VALS(bssgp_flush_action_vals), 0x0, @@ -11712,52 +5966,6 @@ proto_register_bssgp(void) FT_UINT8, BASE_DEC, VALS(bssgp_rim_proto_ver_no_vals), 0x0, NULL, HFILL } }, - - { &hf_bssgp_rcid, - { "Reporting Cell Identity", "bssgp.rcid", - FT_UINT64, BASE_HEX, NULL, 0x0, - NULL, HFILL } - }, - { &hf_bssgp_rrc_si_msg_type, - { "RRC SI type", "bssgp.rrc_si_type", - FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_msg_rr_strings), 0x0, - NULL, HFILL } - }, - { &hf_ran_inf_req_pdu_type_ext, - { "PDU Type Extension", "bssgp.ran_inf_req_pdu_type_ext", - FT_UINT8, BASE_DEC, VALS(ran_inf_req_pdu_type_ext_vals), 0x0e, - NULL, HFILL } - }, - { &hf_ran_inf_pdu_type_ext, - { "PDU Type Extension", "bssgp.ran_req_pdu_type_ext", - FT_UINT8, BASE_DEC, VALS(ran_inf_pdu_type_ext_vals), 0x0e, - NULL, HFILL } - }, - { &hf_bssgp_tmsi_ptmsi, - { "TMSI/PTMSI", "bssgp.tmsi_ptmsi", - FT_UINT32, BASE_HEX, NULL, 0x0, - NULL, HFILL } - }, - { &hf_bssgp_imsi, - { "IMSI", "bssgp.imsi", - FT_STRING, BASE_NONE, NULL, 0x0, - NULL, HFILL } - }, - { &hf_bssgp_imei, - { "IMEI", "bssgp.imei", - FT_STRING, BASE_NONE, NULL, 0x0, - NULL, HFILL } - }, - { &hf_bssgp_imeisv, - { "IMEISV", "bssgp.imeisv", - FT_STRING, BASE_NONE, NULL, 0x0, - NULL, HFILL } - }, - { &hf_bssgp_nri, - { "NRI", "bssgp.nri", - FT_UINT16, BASE_DEC, NULL, 0x0, - NULL, HFILL } - }, { &hf_bssgp_delay_val, { "Delay Value (in centi-seconds)", "bssgp.delay_val", FT_UINT16, BASE_DEC, NULL, 0x0, @@ -11888,7 +6096,12 @@ proto_register_bssgp(void) { &hf_bssgp_bucket_full_ratio, { "Ratio of the bucket that is filled up with data", "bssgp.bucket_full_ratio", FT_UINT8, BASE_DEC, NULL, 0x0, - "Bcurrent x (100 / Bmax)", HFILL } + "B current x (100 / Bmax)", HFILL } + }, + { &hf_bssgp_b_pfc, + { "B_PFC: Bucket Full Ratio of the PFC", "bssgp.b_pfc", + FT_UINT8, BASE_DEC, NULL, 0x0, + "B current x (100 / Bmax)", HFILL } }, { &hf_bssgp_precedence, @@ -12020,61 +6233,19 @@ proto_register_bssgp(void) }; /* Setup protocol subtree array */ -#define NUM_INDIVIDUAL_ELEMS 51 +#define NUM_INDIVIDUAL_ELEMS 9 gint *ett[NUM_INDIVIDUAL_ELEMS + NUM_BSSGP_ELEM + NUM_BSSGP_MSG]; ett[0] = &ett_bssgp; - ett[1] = &ett_bssgp_qos_profile; - ett[2] = &ett_bssgp_gprs_timer; - ett[3] = &ett_bssgp_cell_identifier; - ett[4] = &ett_bssgp_channel_needed; - ett[5] = &ett_bssgp_drx_parameters; - ett[6] = &ett_bssgp_mobile_identity; - ett[7] = &ett_bssgp_priority; - ett[8] = &ett_bssgp_lsa_identifier_list; - ett[9] = &ett_bssgp_lsa_information; - ett[10] = &ett_bssgp_lsa_information_lsa_identification_and_attributes; - ett[11] = &ett_bssgp_abqp; - ett[12] = &ett_bssgp_lcs_qos; - ett[13] = &ett_bssgp_lcs_client_type; - ett[14] = &ett_bssgp_requested_gps_assistance_data; - ett[15] = &ett_bssgp_requested_gps_assistance_data_satellite; - ett[16] = &ett_bssgp_location_type; - ett[17] = &ett_bssgp_positioning_data_positioning_method; - ett[18] = &ett_bssgp_lcs_cause; - ett[19] = &ett_bssgp_lcs_capability; - ett[20] = &ett_bssgp_rrlp_flags; - ett[21] = &ett_bssgp_rim_pdu_indications; - ett[22] = &ett_bssgp_mcc; - ett[23] = &ett_bssgp_mnc; - ett[24] = &ett_bssgp_routing_area; - ett[25] = &ett_bssgp_location_area; - ett[26] = &ett_bssgp_rai_ci; - ett[27] = &ett_bssgp_ran_information_request_application_container; - ett[28] = &ett_bssgp_rim_routing_information; - ett[29] = &ett_bssgp_ran_information_request_container_unit; - ett[30] = &ett_bssgp_ran_information_container_unit; - ett[31] = &ett_bssgp_pfc_flow_control_parameters; - ett[32] = &ett_bssgp_pfc_flow_control_parameters_pfc; - ett[33] = &ett_bssgp_global_cn_id; - ett[34] = &ett_bssgp_ms_radio_access_capability; - ett[35] = &ett_bssgp_feature_bitmap; - ett[36] = &ett_bssgp_positioning_data; - ett[37] = &ett_bssgp_msrac_value_part; - ett[38] = &ett_bssgp_msrac_additional_access_technologies; - ett[39] = &ett_bssgp_msrac_access_capabilities; - ett[40] = &ett_bssgp_msrac_a5_bits; - ett[41] = &ett_bssgp_msrac_multislot_capability; - ett[42] = &ett_bssgp_tlli; - ett[43] = &ett_bssgp_tmsi_ptmsi; - ett[44] = &ett_bssgp_new; - ett[45] = &ett_bssgp_pfcs_to_be_set_up_list; - ett[46] = &ett_bssgp_pfcs_to_be_set_up_list_pft; - ett[47] = &ett_bssgp_pfcs_to_be_set_up_list_abqp; - ett[48] = &ett_bssgp_pfcs_to_be_set_up_list_arp; - ett[49] = &ett_bssgp_pfcs_to_be_set_up_list_t10; - ett[50] = &ett_bssgp_list_of_setup_pfcs; + ett[1] = &ett_bssgp_list_of_setup_pfcs; + ett[2] = &ett_bssgp_pfcs_to_be_set_up_list_t10; + ett[3] = &ett_bssgp_pfcs_to_be_set_up_list_arp; + ett[4] = &ett_bssgp_pfcs_to_be_set_up_list_abqp; + ett[5] = &ett_bssgp_pfcs_to_be_set_up_list_pft; + ett[6] = &ett_bssgp_pfcs_to_be_set_up_list; + ett[7] = &ett_bssgp_new; + ett[8] = &ett_bssgp_pfc_flow_control_parameters_pfc; last_offset = NUM_INDIVIDUAL_ELEMS; |