E2AP: moving towards a better design
This commit is contained in:
parent
d11826a051
commit
6d5496f192
|
@ -121,6 +121,7 @@ set(CLEAN_ASN1_DISSECTOR_SRC
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/packet-isdn-sup.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-its.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-kerberos.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-kpm-v2.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-lcsap.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-ldap.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/packet-lnpdqp.c
|
||||
|
|
|
@ -63,6 +63,7 @@ set(ASN1_SRC_DIRS
|
|||
isdn-sup
|
||||
its
|
||||
kerberos
|
||||
kpm-v2
|
||||
lcsap
|
||||
ldap
|
||||
lnpdqp
|
||||
|
|
|
@ -12,7 +12,7 @@ set( PROTOCOL_NAME e2ap )
|
|||
set( PROTO_OPT )
|
||||
|
||||
set( EXPORT_FILES
|
||||
${PROTOCOL_NAME}-exp.cnf
|
||||
${PROTOCOL_NAME}-exp.cnf
|
||||
)
|
||||
|
||||
set( EXT_ASN_FILE_LIST
|
||||
|
@ -26,7 +26,7 @@ set( ASN_FILE_LIST
|
|||
E2AP-PDU-Contents.asn
|
||||
E2AP-PDU-Descriptions.asn
|
||||
e2sm-v3.01.asn
|
||||
e2sm-rc-v3.00.asn
|
||||
e2sm-rc-v1.03.asn
|
||||
e2sm-kpm-v3.00.asn
|
||||
e2sm-ni-v1.00.asn
|
||||
)
|
||||
|
|
|
@ -23,7 +23,6 @@ E2SM-KPM-ActionDefinition
|
|||
E2SM-KPM-IndicationHeader
|
||||
E2SM-KPM-IndicationMessage
|
||||
E2SM-KPM-RANfunction-Description
|
||||
#E2SM-KPM-CallProcessID (no such function)
|
||||
|
||||
E2SM-RC-EventTrigger
|
||||
E2SM-RC-ActionDefinition
|
||||
|
@ -35,9 +34,9 @@ E2SM-RC-ControlHeader
|
|||
E2SM-RC-ControlMessage
|
||||
E2SM-RC-ControlOutcome
|
||||
# New for v3
|
||||
E2SM-RC-QueryOutcome
|
||||
E2SM-RC-QueryDefinition
|
||||
E2SM-RC-QueryHeader
|
||||
# E2SM-RC-QueryOutcome
|
||||
# E2SM-RC-QueryDefinition
|
||||
# E2SM-RC-QueryHeader
|
||||
|
||||
|
||||
E2SM-NI-EventTriggerDefinition
|
||||
|
@ -246,18 +245,29 @@ SuccessfulOutcome/value successfulOutcome_value
|
|||
|
||||
#.FN_BODY RANfunctionDefinition VAL_PTR = ¶meter_tvb
|
||||
tvbuff_t *parameter_tvb;
|
||||
|
||||
/* We know that the next thing is a RANFunction-Name, but it's wrapped up in a sequence,
|
||||
so can't silently/hiddenly call ranFunctionName here... */
|
||||
|
||||
%(DEFAULT_BODY)s
|
||||
|
||||
/* Looking for shortName string near beginning of tvb */
|
||||
gboolean found = FALSE;
|
||||
for (int n=KPM_RANFUNCTIONS; n<MAX_RANFUNCTIONS; n++) {
|
||||
/* For each RAN function name.. */
|
||||
for (int n=KPM_RANFUNCTIONS; n<MAX_RANFUNCTIONS && !found; n++) {
|
||||
guint32 tvb_len = tvb_captured_length(parameter_tvb);
|
||||
guint name_len = (gint)strlen(g_ran_functioname_table[n].name);
|
||||
guint name_len = (gint)strlen(g_ran_function_name_table[n]);
|
||||
/* For each of several byte positions.. */
|
||||
for (int m=0; (m<30) && ((m+name_len+1))<tvb_len; m++) {
|
||||
if (tvb_strneql(parameter_tvb, m, g_ran_functioname_table[n].name, name_len) == 0) {
|
||||
/* Call the set's dissector */
|
||||
g_ran_functioname_table[n].functions.ran_function_definition_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
found = TRUE;
|
||||
break;
|
||||
/* Have we found a match on the name? */
|
||||
if (tvb_strneql(parameter_tvb, m, g_ran_function_name_table[n], name_len) == 0) {
|
||||
/* TODO: we don't yet know the OID (hopefully won't make a difference for this message though...),
|
||||
so for now just call with the first/only available dissector for this RAN Function name */
|
||||
if (g_ran_functions_available_dissectors[n].num_available_dissectors) {
|
||||
g_ran_functions_available_dissectors[n].ran_function_dissectors[0]->functions.ran_function_definition_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -267,53 +277,82 @@ SuccessfulOutcome/value successfulOutcome_value
|
|||
"ShortName does not match any known Service Model");
|
||||
}
|
||||
|
||||
#.FN_BODY RANfunction-Name/ranFunction-ShortName VAL_PTR=&value_tvb
|
||||
tvbuff_t *value_tvb;
|
||||
%(DEFAULT_BODY)s
|
||||
if (!actx->pinfo->fd->visited) {
|
||||
/* N.B. too early to work out exact dissector, as don't have OID yet */
|
||||
e2ap_store_ran_function_mapping(actx->pinfo,
|
||||
tvb_get_string_enc(wmem_packet_scope(), value_tvb, 0, tvb_captured_length(value_tvb), ENC_ASCII));
|
||||
}
|
||||
|
||||
|
||||
#.FN_BODY RANfunction-Name/ranFunction-E2SM-OID VAL_PTR = ¶meter_tvb
|
||||
tvbuff_t *parameter_tvb;
|
||||
%(DEFAULT_BODY)s
|
||||
e2ap_update_ran_function_mapping(actx->pinfo, tree, parameter_tvb,
|
||||
tvb_get_string_enc(actx->pinfo->pool, parameter_tvb, 0,
|
||||
tvb_captured_length(parameter_tvb), ENC_ASCII));
|
||||
|
||||
|
||||
#.FN_BODY RICcontrolHeader VAL_PTR = ¶meter_tvb
|
||||
tvbuff_t *parameter_tvb;
|
||||
%(DEFAULT_BODY)s
|
||||
ran_function_pointers_t* functions = lookup_ranfunction_pointers(actx->pinfo, tree, parameter_tvb);
|
||||
if (functions && functions->ric_control_header_dissector) {
|
||||
functions->ric_control_header_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
ran_function_dissector_t* dissector = lookup_ranfunction_dissector(actx->pinfo, tree, parameter_tvb);
|
||||
if (dissector) {
|
||||
if (dissector->functions.ric_control_header_dissector) {
|
||||
dissector->functions.ric_control_header_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#.FN_BODY RICcontrolMessage VAL_PTR = ¶meter_tvb
|
||||
tvbuff_t *parameter_tvb;
|
||||
%(DEFAULT_BODY)s
|
||||
ran_function_pointers_t* functions = lookup_ranfunction_pointers(actx->pinfo, tree, parameter_tvb);
|
||||
if (functions && functions->ric_control_message_dissector) {
|
||||
functions->ric_control_message_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
ran_function_dissector_t* dissector = lookup_ranfunction_dissector(actx->pinfo, tree, parameter_tvb);
|
||||
if (dissector) {
|
||||
if (dissector->functions.ric_control_message_dissector) {
|
||||
dissector->functions.ric_control_message_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#.FN_BODY RICcontrolOutcome VAL_PTR = ¶meter_tvb
|
||||
tvbuff_t *parameter_tvb;
|
||||
%(DEFAULT_BODY)s
|
||||
ran_function_pointers_t* functions = lookup_ranfunction_pointers(actx->pinfo, tree, parameter_tvb);
|
||||
if (functions && functions->ric_control_outcome_dissector) {
|
||||
functions->ric_control_outcome_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
ran_function_dissector_t* dissector = lookup_ranfunction_dissector(actx->pinfo, tree, parameter_tvb);
|
||||
if (dissector) {
|
||||
if (dissector->functions.ric_control_outcome_dissector) {
|
||||
dissector->functions.ric_control_outcome_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#.FN_BODY RICqueryOutcome VAL_PTR = ¶meter_tvb
|
||||
tvbuff_t *parameter_tvb;
|
||||
%(DEFAULT_BODY)s
|
||||
ran_function_pointers_t* functions = lookup_ranfunction_pointers(actx->pinfo, tree, parameter_tvb);
|
||||
if (functions && functions->ric_query_outcome_dissector) {
|
||||
functions->ric_query_outcome_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
ran_function_dissector_t* dissector = lookup_ranfunction_dissector(actx->pinfo, tree, parameter_tvb);
|
||||
if (dissector) {
|
||||
if (dissector->functions.ric_query_outcome_dissector) {
|
||||
dissector->functions.ric_query_outcome_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#.FN_BODY RICqueryDefinition VAL_PTR = ¶meter_tvb
|
||||
tvbuff_t *parameter_tvb;
|
||||
%(DEFAULT_BODY)s
|
||||
ran_function_pointers_t* functions = lookup_ranfunction_pointers(actx->pinfo, tree, parameter_tvb);
|
||||
if (functions && functions->ric_query_definition_dissector) {
|
||||
functions->ric_query_definition_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
ran_function_dissector_t* dissector = lookup_ranfunction_dissector(actx->pinfo, tree, parameter_tvb);
|
||||
if (dissector) {
|
||||
if (dissector->functions.ric_query_definition_dissector) {
|
||||
dissector->functions.ric_query_definition_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#.FN_BODY RICqueryHeader VAL_PTR = ¶meter_tvb
|
||||
tvbuff_t *parameter_tvb;
|
||||
%(DEFAULT_BODY)s
|
||||
ran_function_pointers_t* functions = lookup_ranfunction_pointers(actx->pinfo, tree, parameter_tvb);
|
||||
if (functions && functions->ric_query_header_dissector) {
|
||||
functions->ric_query_header_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
ran_function_dissector_t* dissector = lookup_ranfunction_dissector(actx->pinfo, tree, parameter_tvb);
|
||||
if (dissector) {
|
||||
if (dissector->functions.ric_query_header_dissector) {
|
||||
dissector->functions.ric_query_header_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -321,41 +360,51 @@ SuccessfulOutcome/value successfulOutcome_value
|
|||
#.FN_BODY RICeventTriggerDefinition VAL_PTR = ¶meter_tvb
|
||||
tvbuff_t *parameter_tvb;
|
||||
%(DEFAULT_BODY)s
|
||||
ran_function_pointers_t* functions = lookup_ranfunction_pointers(actx->pinfo, tree, parameter_tvb);
|
||||
if (functions && functions->ran_event_trigger_dissector) {
|
||||
functions->ran_event_trigger_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
ran_function_dissector_t* dissector = lookup_ranfunction_dissector(actx->pinfo, tree, parameter_tvb);
|
||||
if (dissector) {
|
||||
if (dissector->functions.ran_event_trigger_dissector) {
|
||||
dissector->functions.ran_event_trigger_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#.FN_BODY RICactionDefinition VAL_PTR = ¶meter_tvb
|
||||
tvbuff_t *parameter_tvb;
|
||||
%(DEFAULT_BODY)s
|
||||
ran_function_pointers_t* functions = lookup_ranfunction_pointers(actx->pinfo, tree, parameter_tvb);
|
||||
if (functions && functions->ran_action_definition_dissector) {
|
||||
functions->ran_action_definition_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
ran_function_dissector_t* dissector = lookup_ranfunction_dissector(actx->pinfo, tree, parameter_tvb);
|
||||
if (dissector) {
|
||||
if (dissector->functions.ran_action_definition_dissector) {
|
||||
dissector->functions.ran_action_definition_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#.FN_BODY RICindicationHeader VAL_PTR = ¶meter_tvb
|
||||
tvbuff_t *parameter_tvb;
|
||||
%(DEFAULT_BODY)s
|
||||
ran_function_pointers_t* functions = lookup_ranfunction_pointers(actx->pinfo, tree, parameter_tvb);
|
||||
if (functions && functions->ran_indication_header_dissector) {
|
||||
functions->ran_indication_header_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
ran_function_dissector_t* dissector = lookup_ranfunction_dissector(actx->pinfo, tree, parameter_tvb);
|
||||
if (dissector) {
|
||||
if (dissector->functions.ran_indication_header_dissector) {
|
||||
dissector->functions.ran_indication_header_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#.FN_BODY RICindicationMessage VAL_PTR = ¶meter_tvb
|
||||
tvbuff_t *parameter_tvb;
|
||||
%(DEFAULT_BODY)s
|
||||
ran_function_pointers_t* functions = lookup_ranfunction_pointers(actx->pinfo, tree, parameter_tvb);
|
||||
if (functions && functions->ran_indication_message_dissector) {
|
||||
functions->ran_indication_message_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
ran_function_dissector_t* dissector = lookup_ranfunction_dissector(actx->pinfo, tree, parameter_tvb);
|
||||
if (dissector) {
|
||||
if (dissector->functions.ran_indication_message_dissector) {
|
||||
dissector->functions.ran_indication_message_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#.FN_BODY RICcallProcessID VAL_PTR = ¶meter_tvb
|
||||
tvbuff_t *parameter_tvb;
|
||||
%(DEFAULT_BODY)s
|
||||
ran_function_pointers_t* functions = lookup_ranfunction_pointers(actx->pinfo, tree, parameter_tvb);
|
||||
if (functions && functions->ran_callprocessid_dissector) {
|
||||
functions->ran_callprocessid_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
ran_function_dissector_t* dissector = lookup_ranfunction_dissector(actx->pinfo, tree, parameter_tvb);
|
||||
if (dissector) {
|
||||
if (dissector->functions.ran_callprocessid_dissector) {
|
||||
dissector->functions.ran_callprocessid_dissector(parameter_tvb, actx->pinfo, tree, NULL);
|
||||
}
|
||||
}
|
||||
# ################################################################################
|
||||
|
||||
|
@ -663,14 +712,6 @@ RICQueryResponse N e2ap.proc.sout id-RICquery
|
|||
e2ap_data->ran_function_id = value;
|
||||
|
||||
|
||||
#.FN_BODY RANfunction-Name/ranFunction-ShortName VAL_PTR=&value_tvb
|
||||
tvbuff_t *value_tvb;
|
||||
%(DEFAULT_BODY)s
|
||||
struct e2ap_private_data *e2ap_data = e2ap_get_private_data(actx->pinfo);
|
||||
ran_functionid_table_t *table = get_ran_functionid_table(actx->pinfo);
|
||||
store_ran_function_mapping(actx->pinfo, table, e2ap_data,
|
||||
tvb_get_string_enc(wmem_packet_scope(), value_tvb, 0, tvb_captured_length(value_tvb), ENC_ASCII));
|
||||
|
||||
#.FN_BODY GlobalgNB-ID/gnb-id
|
||||
int start_offset = offset;
|
||||
%(DEFAULT_BODY)s
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,11 +8,10 @@
|
|||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*
|
||||
* References: ORAN-WG3.E2AP-v02.01, ORAN-WG3.E2SM-KPM-v02.02, ORAN-WG3.E2SM-RC.01.02
|
||||
* References: ORAN-WG3.E2AP-v03.00, ORAN-WG3.E2SM-KPM-v03.00, ORAN-WG3.E2SM-RC.03.00
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include <epan/packet.h>
|
||||
#include <epan/strutil.h>
|
||||
|
@ -22,9 +21,8 @@
|
|||
#include <epan/expert.h>
|
||||
#include <epan/proto_data.h>
|
||||
#include <epan/conversation.h>
|
||||
#include <epan/exceptions.h>
|
||||
#include <epan/show_exception.h>
|
||||
#include <epan/to_str.h>
|
||||
#include <epan/oids.h>
|
||||
|
||||
#include "packet-e2ap.h"
|
||||
#include "packet-per.h"
|
||||
|
@ -50,18 +48,23 @@ static int hf_e2ap_unmapped_ran_function_id = -1;
|
|||
static int hf_e2ap_ran_function_name_not_recognised = -1;
|
||||
static int hf_e2ap_ran_function_setup_frame = -1;
|
||||
|
||||
|
||||
static int hf_e2ap_dissector_version= -1;
|
||||
static int hf_e2ap_frame_version = -1;
|
||||
|
||||
/* Initialize the subtree pointers */
|
||||
static gint ett_e2ap = -1;
|
||||
|
||||
static expert_field ei_e2ap_ran_function_names_no_match = EI_INIT;
|
||||
static expert_field ei_e2ap_ran_function_id_not_mapped = EI_INIT;
|
||||
static expert_field ei_e2ap_ran_function_dissector_mismatch = EI_INIT;
|
||||
|
||||
#include "packet-e2ap-ett.c"
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
static int dissect_e2ap_RANfunction_Name(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
|
||||
|
||||
static int dissect_E2SM_KPM_EventTriggerDefinition_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
static int dissect_E2SM_KPM_ActionDefinition_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
static int dissect_E2SM_KPM_IndicationHeader_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
|
@ -77,9 +80,9 @@ static int dissect_E2SM_RC_CallProcessID_PDU(tvbuff_t *tvb _U_, packet_info *pin
|
|||
static int dissect_E2SM_RC_ControlHeader_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
static int dissect_E2SM_RC_ControlMessage_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
static int dissect_E2SM_RC_ControlOutcome_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
static int dissect_E2SM_RC_QueryOutcome_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
static int dissect_E2SM_RC_QueryDefinition_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
static int dissect_E2SM_RC_QueryHeader_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
//static int dissect_E2SM_RC_QueryOutcome_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
//static int dissect_E2SM_RC_QueryDefinition_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
//static int dissect_E2SM_RC_QueryHeader_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
|
||||
static int dissect_E2SM_NI_EventTriggerDefinition_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
static int dissect_E2SM_NI_ActionDefinition_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
|
@ -91,8 +94,6 @@ static int dissect_E2SM_NI_ControlHeader_PDU(tvbuff_t *tvb _U_, packet_info *pin
|
|||
static int dissect_E2SM_NI_ControlMessage_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
static int dissect_E2SM_NI_ControlOutcome_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
|
||||
|
||||
|
||||
enum {
|
||||
INITIATING_MESSAGE,
|
||||
SUCCESSFUL_OUTCOME,
|
||||
|
@ -107,7 +108,7 @@ typedef struct _e2ap_ctx_t {
|
|||
} e2ap_ctx_t;
|
||||
|
||||
|
||||
|
||||
/* Temporary private info to remember while dissecting frame */
|
||||
struct e2ap_private_data {
|
||||
guint32 procedure_code;
|
||||
guint32 protocol_ie_id;
|
||||
|
@ -122,6 +123,7 @@ struct e2ap_private_data {
|
|||
dissector_handle_t component_configuration_dissector;
|
||||
};
|
||||
|
||||
/* Lookup temporary private info */
|
||||
static struct e2ap_private_data*
|
||||
e2ap_get_private_data(packet_info *pinfo)
|
||||
{
|
||||
|
@ -138,102 +140,24 @@ e2ap_get_private_data(packet_info *pinfo)
|
|||
/* TODO: unfortunately, it seems that different versions of these protocols are not backward-compatible, so */
|
||||
/* it would be good to show where (going by OID) the dissector isn't at the same version as the message.. */
|
||||
/* An alternative would be to have multiple versions of each protocol and have them register in tables... */
|
||||
typedef int (*pdu_dissector_t)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data);
|
||||
|
||||
/* Function pointers for a RANFunction */
|
||||
typedef struct {
|
||||
pdu_dissector_t ran_function_definition_dissector;
|
||||
|
||||
pdu_dissector_t ric_control_header_dissector;
|
||||
pdu_dissector_t ric_control_message_dissector;
|
||||
pdu_dissector_t ric_control_outcome_dissector;
|
||||
/* new for v3 */
|
||||
pdu_dissector_t ric_query_outcome_dissector;
|
||||
pdu_dissector_t ric_query_definition_dissector;
|
||||
pdu_dissector_t ric_query_header_dissector;
|
||||
|
||||
pdu_dissector_t ran_action_definition_dissector;
|
||||
pdu_dissector_t ran_indication_message_dissector;
|
||||
pdu_dissector_t ran_indication_header_dissector;
|
||||
pdu_dissector_t ran_callprocessid_dissector;
|
||||
pdu_dissector_t ran_event_trigger_dissector;
|
||||
} ran_function_pointers_t;
|
||||
|
||||
typedef enum {
|
||||
MIN_RANFUNCTIONS,
|
||||
KPM_RANFUNCTIONS=0,
|
||||
RIC_RANFUNCTIONS,
|
||||
NI_RANFUNCTIONS,
|
||||
MAX_RANFUNCTIONS
|
||||
} ran_function_t;
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
ran_function_pointers_t functions;
|
||||
} ran_function_name_mapping_t;
|
||||
|
||||
/* Static table mapping from string -> ran_function */
|
||||
static const ran_function_name_mapping_t g_ran_functioname_table[MAX_RANFUNCTIONS] =
|
||||
static const char* g_ran_function_name_table[MAX_RANFUNCTIONS] =
|
||||
{
|
||||
{ "ORAN-E2SM-KPM", { dissect_E2SM_KPM_RANfunction_Description_PDU,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
dissect_E2SM_KPM_ActionDefinition_PDU,
|
||||
dissect_E2SM_KPM_IndicationMessage_PDU,
|
||||
dissect_E2SM_KPM_IndicationHeader_PDU,
|
||||
NULL, /* no dissect_E2SM_KPM_CallProcessID_PDU */
|
||||
dissect_E2SM_KPM_EventTriggerDefinition_PDU
|
||||
}
|
||||
},
|
||||
{ "ORAN-E2SM-RC", { dissect_E2SM_RC_RANFunctionDefinition_PDU,
|
||||
|
||||
dissect_E2SM_RC_ControlHeader_PDU,
|
||||
dissect_E2SM_RC_ControlMessage_PDU,
|
||||
dissect_E2SM_RC_ControlOutcome_PDU,
|
||||
/* new for v3 */
|
||||
dissect_E2SM_RC_QueryOutcome_PDU,
|
||||
dissect_E2SM_RC_QueryDefinition_PDU,
|
||||
dissect_E2SM_RC_QueryHeader_PDU,
|
||||
|
||||
dissect_E2SM_RC_ActionDefinition_PDU,
|
||||
dissect_E2SM_RC_IndicationMessage_PDU,
|
||||
dissect_E2SM_RC_IndicationHeader_PDU,
|
||||
dissect_E2SM_RC_CallProcessID_PDU,
|
||||
dissect_E2SM_RC_EventTrigger_PDU
|
||||
}
|
||||
},
|
||||
{ "ORAN-E2SM-NI", { dissect_E2SM_NI_RANfunction_Description_PDU,
|
||||
|
||||
dissect_E2SM_NI_ControlHeader_PDU,
|
||||
dissect_E2SM_NI_ControlMessage_PDU,
|
||||
dissect_E2SM_NI_ControlOutcome_PDU,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
dissect_E2SM_NI_ActionDefinition_PDU,
|
||||
dissect_E2SM_NI_IndicationMessage_PDU,
|
||||
dissect_E2SM_NI_IndicationHeader_PDU,
|
||||
dissect_E2SM_NI_CallProcessID_PDU,
|
||||
dissect_E2SM_NI_EventTriggerDefinition_PDU
|
||||
}
|
||||
}
|
||||
"ORAN-E2SM-KPM",
|
||||
"ORAN-E2SM-RC",
|
||||
"ORAN-E2SM-NI"
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Per-conversation mapping: ranFunctionId -> ran_function */
|
||||
/* Per-conversation mapping: ranFunctionId -> ran_function+dissector */
|
||||
typedef struct {
|
||||
guint32 setup_frame;
|
||||
guint32 ran_function_id;
|
||||
ran_function_t ran_function;
|
||||
ran_function_pointers_t *ran_function_pointers;
|
||||
char oid[MAX_OID_LEN]; // i.e., OID from setupRequest
|
||||
ran_function_dissector_t *dissector;
|
||||
} ran_function_id_mapping_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -247,27 +171,49 @@ static const char *ran_function_to_str(ran_function_t ran_function)
|
|||
switch (ran_function) {
|
||||
case KPM_RANFUNCTIONS:
|
||||
return "KPM";
|
||||
case RIC_RANFUNCTIONS:
|
||||
return "RIC";
|
||||
case RC_RANFUNCTIONS:
|
||||
return "RC";
|
||||
case NI_RANFUNCTIONS:
|
||||
return "NI";
|
||||
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
/* Table of RAN Function tables, indexed by gnbId (bytes) */
|
||||
typedef struct {
|
||||
#define MAX_GNBS 6
|
||||
guint32 num_gnbs;
|
||||
struct {
|
||||
guint32 len;
|
||||
guint8 value[MAX_GNB_ID_BYTES];
|
||||
guint8 id_value[MAX_GNB_ID_BYTES];
|
||||
guint32 id_len;
|
||||
ran_functionid_table_t *ran_function_table;
|
||||
} gnb[MAX_GNBS];
|
||||
} gnb_ran_functions_t;
|
||||
|
||||
static gnb_ran_functions_t s_gnb_ran_functions;
|
||||
static gnb_ran_functions_t s_gnb_ran_functions_table;
|
||||
|
||||
|
||||
/* Table of available dissectors for each RAN function */
|
||||
typedef struct {
|
||||
guint32 num_available_dissectors;
|
||||
#define MAX_DISSECTORS_PER_RAN_FUNCTION 3
|
||||
ran_function_dissector_t* ran_function_dissectors[MAX_DISSECTORS_PER_RAN_FUNCTION];
|
||||
} ran_function_available_dissectors_t;
|
||||
|
||||
/* Available dissectors should be set here */
|
||||
static ran_function_available_dissectors_t g_ran_functions_available_dissectors[MAX_RANFUNCTIONS];
|
||||
|
||||
/* TODO: will be called from outside this file by separate dissectors */
|
||||
void register_e2ap_ran_function_dissector(ran_function_t ran_function, ran_function_dissector_t *dissector)
|
||||
{
|
||||
if ((ran_function >= MIN_RANFUNCTIONS) && (ran_function <= MAX_RANFUNCTIONS)) {
|
||||
ran_function_available_dissectors_t *available_dissectors = &g_ran_functions_available_dissectors[ran_function];
|
||||
if (available_dissectors->num_available_dissectors < MAX_DISSECTORS_PER_RAN_FUNCTION) {
|
||||
available_dissectors->ran_function_dissectors[available_dissectors->num_available_dissectors++] = dissector;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Get RANfunctionID table from conversation data - create new if necessary */
|
||||
|
@ -298,8 +244,11 @@ static ran_functionid_table_t* get_ran_functionid_table(packet_info *pinfo)
|
|||
|
||||
|
||||
/* Store new RANfunctionID -> Service Model mapping in table */
|
||||
static void store_ran_function_mapping(packet_info *pinfo, ran_functionid_table_t *table, struct e2ap_private_data *e2ap_data, const char *name)
|
||||
void e2ap_store_ran_function_mapping(packet_info *pinfo, const char *name)
|
||||
{
|
||||
struct e2ap_private_data *e2ap_data = e2ap_get_private_data(pinfo);
|
||||
ran_functionid_table_t *table = get_ran_functionid_table(pinfo);
|
||||
|
||||
if (!name) {
|
||||
return;
|
||||
}
|
||||
|
@ -312,13 +261,18 @@ static void store_ran_function_mapping(packet_info *pinfo, ran_functionid_table_
|
|||
guint32 ran_function_id = e2ap_data->ran_function_id;
|
||||
|
||||
ran_function_t ran_function = MAX_RANFUNCTIONS; /* i.e. invalid */
|
||||
ran_function_pointers_t *ran_function_pointers = NULL;
|
||||
ran_function_dissector_t *ran_function_dissector = NULL;
|
||||
|
||||
/* Check known RAN functions */
|
||||
/* Check known RAN function names */
|
||||
for (int n=MIN_RANFUNCTIONS; n < MAX_RANFUNCTIONS; n++) {
|
||||
if (strcmp(name, g_ran_functioname_table[n].name) == 0) {
|
||||
if (strcmp(name, g_ran_function_name_table[n]) == 0) {
|
||||
ran_function = n;
|
||||
ran_function_pointers = (ran_function_pointers_t*)&(g_ran_functioname_table[n].functions);
|
||||
|
||||
/* Don't know OID yet, so for now, just choose first/only one */
|
||||
/* TODO: is latest one likely to be more compatible? First fields (at least) come from E2SM.. */
|
||||
if (g_ran_functions_available_dissectors[table->entries[n].ran_function].num_available_dissectors) {
|
||||
ran_function_dissector = g_ran_functions_available_dissectors[table->entries[n].ran_function].ran_function_dissectors[0];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -328,7 +282,7 @@ static void store_ran_function_mapping(packet_info *pinfo, ran_functionid_table_
|
|||
return;
|
||||
}
|
||||
|
||||
/* If ID already mapped, ignore */
|
||||
/* If ID already mapped, can stop here */
|
||||
for (guint n=0; n < table->num_entries; n++) {
|
||||
if (table->entries[n].ran_function_id == ran_function_id) {
|
||||
return;
|
||||
|
@ -340,7 +294,7 @@ static void store_ran_function_mapping(packet_info *pinfo, ran_functionid_table_
|
|||
table->entries[idx].setup_frame = pinfo->num;
|
||||
table->entries[idx].ran_function_id = ran_function_id;
|
||||
table->entries[idx].ran_function = ran_function;
|
||||
table->entries[idx].ran_function_pointers = ran_function_pointers;
|
||||
table->entries[idx].dissector = ran_function_dissector;
|
||||
|
||||
/* When add first entry, also want to set up table from gnbId -> table */
|
||||
if (idx == 0) {
|
||||
|
@ -348,10 +302,10 @@ static void store_ran_function_mapping(packet_info *pinfo, ran_functionid_table_
|
|||
guint8 *id_value = &e2ap_data->gnb_id_bytes[0];
|
||||
|
||||
gboolean found = FALSE;
|
||||
for (guint n=0; n<s_gnb_ran_functions.num_gnbs; n++) {
|
||||
if ((s_gnb_ran_functions.gnb[n].len = id_len) &&
|
||||
(memcmp(s_gnb_ran_functions.gnb[n].value, id_value, id_len) == 0)) {
|
||||
// Already have an entry for this gnb.
|
||||
for (guint n=0; n<s_gnb_ran_functions_table.num_gnbs; n++) {
|
||||
if ((s_gnb_ran_functions_table.gnb[n].id_len = id_len) &&
|
||||
(memcmp(s_gnb_ran_functions_table.gnb[n].id_value, id_value, id_len) == 0)) {
|
||||
/* Already have an entry for this gnb. */
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
|
@ -359,51 +313,174 @@ static void store_ran_function_mapping(packet_info *pinfo, ran_functionid_table_
|
|||
|
||||
if (!found) {
|
||||
/* Add entry (if room for 1 more) */
|
||||
guint32 new_idx = s_gnb_ran_functions.num_gnbs;
|
||||
guint32 new_idx = s_gnb_ran_functions_table.num_gnbs;
|
||||
if (new_idx < MAX_GNBS-1) {
|
||||
s_gnb_ran_functions.gnb[new_idx].len = id_len;
|
||||
memcpy(s_gnb_ran_functions.gnb[new_idx].value, id_value, id_len);
|
||||
s_gnb_ran_functions.gnb[new_idx].ran_function_table = table;
|
||||
s_gnb_ran_functions_table.gnb[new_idx].id_len = id_len;
|
||||
memcpy(s_gnb_ran_functions_table.gnb[new_idx].id_value, id_value, id_len);
|
||||
s_gnb_ran_functions_table.gnb[new_idx].ran_function_table = table;
|
||||
|
||||
s_gnb_ran_functions.num_gnbs++;
|
||||
s_gnb_ran_functions_table.num_gnbs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Look for Service Model function pointers, based on current RANFunctionID in pinfo */
|
||||
static ran_function_pointers_t* lookup_ranfunction_pointers(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb)
|
||||
static ran_function_dissector_t* lookup_ranfunction_dissector(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb)
|
||||
{
|
||||
/* Get ranFunctionID from this frame */
|
||||
struct e2ap_private_data *e2ap_data = e2ap_get_private_data(pinfo);
|
||||
guint ran_function_id = e2ap_data->ran_function_id;
|
||||
|
||||
/* Look in table function pointers for this ranFunctionID */
|
||||
/* Get ranFunction table corresponding to this frame's conversation */
|
||||
ran_functionid_table_t *table = get_ran_functionid_table(pinfo);
|
||||
if (!table) {
|
||||
/* There is no ran function table associated with this frame's conversation info */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find the entry in this table corresponding to ran_function_id */
|
||||
for (guint n=0; n < table->num_entries; n++) {
|
||||
if (ran_function_id == table->entries[n].ran_function_id) {
|
||||
/* Point back at the setup frame where this ranfunction was mapped */
|
||||
proto_item *ti = proto_tree_add_uint(tree, hf_e2ap_ran_function_setup_frame,
|
||||
tvb, 0, 0, table->entries[n].setup_frame);
|
||||
/* Also show that mapping */
|
||||
proto_item_append_text(ti, " (%u -> %s)", table->entries[n].ran_function_id, ran_function_to_str(table->entries[n].ran_function));
|
||||
proto_item_set_generated(ti);
|
||||
if (tree) {
|
||||
/* Point back at the setup frame where this ranfunction was mapped */
|
||||
proto_item *ti = proto_tree_add_uint(tree, hf_e2ap_ran_function_setup_frame,
|
||||
tvb, 0, 0, table->entries[n].setup_frame);
|
||||
/* Show that mapping */
|
||||
proto_item_append_text(ti, " (%u -> %s)", table->entries[n].ran_function_id, ran_function_to_str(table->entries[n].ran_function));
|
||||
proto_item_set_generated(ti);
|
||||
|
||||
return table->entries[n].ran_function_pointers;
|
||||
/* Also take the chance to compare signalled and available dissector */
|
||||
char *frame_version = oid_resolved_from_string(pinfo->pool, table->entries[n].oid);
|
||||
ti = proto_tree_add_string(tree, hf_e2ap_frame_version, tvb, 0, 0, frame_version);
|
||||
proto_item_set_generated(ti);
|
||||
|
||||
char *dissector_version = oid_resolved_from_string(pinfo->pool, table->entries[n].dissector->oid);
|
||||
ti = proto_tree_add_string(tree, hf_e2ap_dissector_version, tvb, 0, 0, dissector_version);
|
||||
proto_item_set_generated(ti);
|
||||
|
||||
if (strcmp(frame_version, dissector_version) != 0) {
|
||||
/* Expert info for version mismatch! */
|
||||
expert_add_info_format(pinfo, ti, &ei_e2ap_ran_function_dissector_mismatch,
|
||||
"Dissector version mismatch - frame is %s but dissector is %s",
|
||||
frame_version, dissector_version);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the dissector */
|
||||
return table->entries[n].dissector;
|
||||
}
|
||||
}
|
||||
|
||||
/* No match found.. */
|
||||
proto_item *ti = proto_tree_add_item(tree, hf_e2ap_unmapped_ran_function_id, tvb, 0, 0, ENC_NA);
|
||||
expert_add_info_format(pinfo, ti, &ei_e2ap_ran_function_id_not_mapped,
|
||||
"Service Model not mapped for FunctionID %u", ran_function_id);
|
||||
if (tree) {
|
||||
/* No match found.. */
|
||||
proto_item *ti = proto_tree_add_item(tree, hf_e2ap_unmapped_ran_function_id, tvb, 0, 0, ENC_NA);
|
||||
expert_add_info_format(pinfo, ti, &ei_e2ap_ran_function_id_not_mapped,
|
||||
"Service Model not mapped for FunctionID %u", ran_function_id);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char* lookup_ranfunction_oid(packet_info *pinfo)
|
||||
{
|
||||
/* Get ranFunctionID from this frame */
|
||||
struct e2ap_private_data *e2ap_data = e2ap_get_private_data(pinfo);
|
||||
guint ran_function_id = e2ap_data->ran_function_id;
|
||||
|
||||
/* Get ranFunction table corresponding to this frame's conversation */
|
||||
ran_functionid_table_t *table = get_ran_functionid_table(pinfo);
|
||||
if (!table) {
|
||||
/* There is no ran function table associated with this frame's conversation info */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find the entry in this table corresponding to ran_function_id */
|
||||
for (guint n=0; n < table->num_entries; n++) {
|
||||
if (ran_function_id == table->entries[n].ran_function_id) {
|
||||
return (char*)(table->entries[n].oid);
|
||||
}
|
||||
}
|
||||
|
||||
/* Not found */
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/* We now know the OID - can we set a dissector that is an exact match from what has been signalled? */
|
||||
static void update_dissector_using_oid(packet_info *pinfo, ran_function_t ran_function)
|
||||
{
|
||||
char *frame_oid = lookup_ranfunction_oid(pinfo);
|
||||
|
||||
gboolean found = FALSE;
|
||||
|
||||
/* Look at available dissectors for this RAN function */
|
||||
ran_function_available_dissectors_t *available = &g_ran_functions_available_dissectors[ran_function];
|
||||
if (!available->num_available_dissectors) {
|
||||
/* Oops - none available at all! */
|
||||
return;
|
||||
}
|
||||
|
||||
// Get mapping in use
|
||||
struct e2ap_private_data *e2ap_data = e2ap_get_private_data(pinfo);
|
||||
guint ran_function_id = e2ap_data->ran_function_id;
|
||||
ran_function_id_mapping_t *mapping = NULL;
|
||||
ran_functionid_table_t *table = get_ran_functionid_table(pinfo);
|
||||
/* Find the entry in this table corresponding to ran_function_id */
|
||||
for (guint n=0; n < table->num_entries; n++) {
|
||||
if (ran_function_id == table->entries[n].ran_function_id) {
|
||||
mapping = &(table->entries[n]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mapping) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set dissector pointer in ran_function_id_mapping_t */
|
||||
for (guint32 n=0; n < available->num_available_dissectors; n++) {
|
||||
/* If exact match, set it */
|
||||
if (strcmp(frame_oid, available->ran_function_dissectors[n]->oid) == 0) {
|
||||
mapping->dissector = available->ran_function_dissectors[n];
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If not exact match, just set to first one available (TODO: closest above better?) */
|
||||
if (!found) {
|
||||
mapping->dissector = available->ran_function_dissectors[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Update RANfunctionID -> Service Model mapping in table (now that we know OID) */
|
||||
void e2ap_update_ran_function_mapping(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, const char *oid)
|
||||
{
|
||||
/* Copy OID into table entry (so may be used to choose and be compared with chosen available dissector */
|
||||
struct e2ap_private_data *e2ap_data = e2ap_get_private_data(pinfo);
|
||||
ran_functionid_table_t *table = get_ran_functionid_table(pinfo);
|
||||
ran_function_t ran_function = MAX_RANFUNCTIONS;
|
||||
for (guint n=0; n < table->num_entries; n++) {
|
||||
if (e2ap_data->ran_function_id == table->entries[n].ran_function_id) {
|
||||
ran_function = table->entries[n].ran_function;
|
||||
g_strlcpy(table->entries[n].oid, oid, MAX_OID_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
/* Look up version from oid and show as generated field */
|
||||
char *version = oid_resolved_from_string(pinfo->pool, oid);
|
||||
proto_item *ti = proto_tree_add_string(tree, hf_e2ap_frame_version, tvb, 0, 0, version);
|
||||
proto_item_set_generated(ti);
|
||||
|
||||
// Can now pick most appropriate dissector for this RAN Function name, based upon this OID and the available dissectors.
|
||||
if (ran_function < MAX_RANFUNCTIONS) {
|
||||
if (pinfo->fd->visited) {
|
||||
update_dissector_using_oid(pinfo, ran_function);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This will get used for E2nodeConfigurationUpdate, where we have a gnb-id but haven't seen E2setupRequest */
|
||||
static void update_conversation_from_gnb_id(asn1_ctx_t *actx)
|
||||
{
|
||||
|
@ -431,13 +508,13 @@ static void update_conversation_from_gnb_id(asn1_ctx_t *actx)
|
|||
guint id_len = e2ap_data->gnb_id_len;
|
||||
guint8 *id_value = &e2ap_data->gnb_id_bytes[0];
|
||||
|
||||
for (guint n=0; n<s_gnb_ran_functions.num_gnbs; n++) {
|
||||
if ((s_gnb_ran_functions.gnb[n].len = id_len) &&
|
||||
(memcmp(s_gnb_ran_functions.gnb[n].value, id_value, id_len) == 0)) {
|
||||
for (guint n=0; n<s_gnb_ran_functions_table.num_gnbs; n++) {
|
||||
if ((s_gnb_ran_functions_table.gnb[n].id_len = id_len) &&
|
||||
(memcmp(s_gnb_ran_functions_table.gnb[n].id_value, id_value, id_len) == 0)) {
|
||||
|
||||
/* Have an entry for this gnb. Set direct pointer to existing data (used by original conversation). */
|
||||
/* N.B. This means that no further updates for the gNB are expected on different conversations.. */
|
||||
p_conv_data = s_gnb_ran_functions.gnb[n].ran_function_table;
|
||||
p_conv_data = s_gnb_ran_functions_table.gnb[n].ran_function_table;
|
||||
conversation_add_proto_data(p_conv, proto_e2ap, p_conv_data);
|
||||
|
||||
/* TODO: may want to try to add a generated field to pass back to E2setupRequest where RAN function mappings were first seen? */
|
||||
|
@ -548,7 +625,7 @@ dissect_e2ap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_
|
|||
|
||||
static void e2ap_init_protocol(void)
|
||||
{
|
||||
s_gnb_ran_functions.num_gnbs = 0;
|
||||
s_gnb_ran_functions_table.num_gnbs = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -562,6 +639,90 @@ proto_reg_handoff_e2ap(void)
|
|||
dissector_add_uint("sctp.ppi", E2_DU_PROTOCOL_ID, e2ap_handle);
|
||||
|
||||
#include "packet-e2ap-dis-tab.c"
|
||||
|
||||
/********************************/
|
||||
/* Known OIDs for RAN providers */
|
||||
|
||||
/* KPM */
|
||||
oid_add_from_string("KPM v1", "1.3.6.1.4.1.53148.1.1.2.2");
|
||||
oid_add_from_string("KPM v2", "1.3.6.1.4.1.53148.1.2.2.2");
|
||||
oid_add_from_string("KPM v3", "1.2.6.1.4.1.53148.1.3.2.2");
|
||||
|
||||
/* RC */
|
||||
// TODO: appears to be the same??? Asking for clarification from ORAN..
|
||||
oid_add_from_string("RC v1", "1.3.6.1.4.1.53148.1.1.2.3");
|
||||
//oid_add_from_string("RC v3", "1.3.6.1.4.1.53148.1.1.2.3");
|
||||
//oid_add_from_string("RC v4", "1.3.6.1.4.1.53148.1.1.2.3");
|
||||
|
||||
/* NI */
|
||||
oid_add_from_string("NI v1", "1.3.6.1.4.1.53148.1.1.2.1");
|
||||
|
||||
/********************************/
|
||||
/* Register 'built-in' dissectors */
|
||||
|
||||
static ran_function_dissector_t kpm_v3 =
|
||||
{ "ORAN-E2SM-KPM", "1.2.6.1.4.1.53148.1.3.2.2", 3, 0,
|
||||
{ dissect_E2SM_KPM_RANfunction_Description_PDU,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
dissect_E2SM_KPM_ActionDefinition_PDU,
|
||||
dissect_E2SM_KPM_IndicationMessage_PDU,
|
||||
dissect_E2SM_KPM_IndicationHeader_PDU,
|
||||
NULL, /* no dissect_E2SM_KPM_CallProcessID_PDU */
|
||||
dissect_E2SM_KPM_EventTriggerDefinition_PDU
|
||||
}
|
||||
};
|
||||
|
||||
static ran_function_dissector_t rc_v1 =
|
||||
{ "ORAN-E2SM-RC", "1.3.6.1.4.1.53148.1.1.2.3", 1, 3,
|
||||
{ dissect_E2SM_RC_RANFunctionDefinition_PDU,
|
||||
|
||||
dissect_E2SM_RC_ControlHeader_PDU,
|
||||
dissect_E2SM_RC_ControlMessage_PDU,
|
||||
dissect_E2SM_RC_ControlOutcome_PDU,
|
||||
/* new for v3 */
|
||||
NULL, //dissect_E2SM_RC_QueryOutcome_PDU,
|
||||
NULL, //dissect_E2SM_RC_QueryDefinition_PDU,
|
||||
NULL, //dissect_E2SM_RC_QueryHeader_PDU,
|
||||
|
||||
dissect_E2SM_RC_ActionDefinition_PDU,
|
||||
dissect_E2SM_RC_IndicationMessage_PDU,
|
||||
dissect_E2SM_RC_IndicationHeader_PDU,
|
||||
dissect_E2SM_RC_CallProcessID_PDU,
|
||||
dissect_E2SM_RC_EventTrigger_PDU
|
||||
}
|
||||
};
|
||||
|
||||
static ran_function_dissector_t ni_v1 =
|
||||
{ "ORAN-E2SM-NI", "1.3.6.1.4.1.53148.1.1.2.1", 1, 0,
|
||||
{ dissect_E2SM_NI_RANfunction_Description_PDU,
|
||||
|
||||
dissect_E2SM_NI_ControlHeader_PDU,
|
||||
dissect_E2SM_NI_ControlMessage_PDU,
|
||||
dissect_E2SM_NI_ControlOutcome_PDU,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
dissect_E2SM_NI_ActionDefinition_PDU,
|
||||
dissect_E2SM_NI_IndicationMessage_PDU,
|
||||
dissect_E2SM_NI_IndicationHeader_PDU,
|
||||
dissect_E2SM_NI_CallProcessID_PDU,
|
||||
dissect_E2SM_NI_EventTriggerDefinition_PDU
|
||||
}
|
||||
};
|
||||
|
||||
/* Register available dissectors. TODO: break these out into separate
|
||||
* ASN.1 protocols that register themselves */
|
||||
register_e2ap_ran_function_dissector(KPM_RANFUNCTIONS, &kpm_v3);
|
||||
register_e2ap_ran_function_dissector(RC_RANFUNCTIONS, &rc_v1);
|
||||
register_e2ap_ran_function_dissector(NI_RANFUNCTIONS, &ni_v1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -584,7 +745,16 @@ void proto_register_e2ap(void) {
|
|||
{ &hf_e2ap_ran_function_setup_frame,
|
||||
{ "RANfunction setup frame", "e2ap.setup-frame",
|
||||
FT_FRAMENUM, BASE_NONE, NULL, 0x0,
|
||||
NULL, HFILL }}
|
||||
NULL, HFILL }},
|
||||
|
||||
{ &hf_e2ap_dissector_version,
|
||||
{ "Version (dissector)", "e2ap.version.dissector",
|
||||
FT_STRING, BASE_NONE, NULL, 0x0,
|
||||
NULL, HFILL }},
|
||||
{ &hf_e2ap_frame_version,
|
||||
{ "Version (frame)", "e2ap.version.frame",
|
||||
FT_STRING, BASE_NONE, NULL, 0x0,
|
||||
NULL, HFILL }},
|
||||
};
|
||||
|
||||
/* List of subtrees */
|
||||
|
@ -596,6 +766,8 @@ void proto_register_e2ap(void) {
|
|||
static ei_register_info ei[] = {
|
||||
{ &ei_e2ap_ran_function_names_no_match, { "e2ap.ran-function-names-no-match", PI_PROTOCOL, PI_WARN, "RAN Function name doesn't match known service models", EXPFILL }},
|
||||
{ &ei_e2ap_ran_function_id_not_mapped, { "e2ap.ran-function-id-not-known", PI_PROTOCOL, PI_WARN, "Service Model not known for RANFunctionID", EXPFILL }},
|
||||
{ &ei_e2ap_ran_function_dissector_mismatch, { "e2ap.ran-function-dissector-version-mismatch", PI_PROTOCOL, PI_WARN, "Available dissector does not match signalled", EXPFILL }},
|
||||
|
||||
};
|
||||
|
||||
expert_module_t* expert_e2ap;
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
# CMakeLists.txt
|
||||
#
|
||||
# Wireshark - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@wireshark.org>
|
||||
# Copyright 1998 Gerald Combs
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
|
||||
set( PROTOCOL_NAME kpm-v2 )
|
||||
|
||||
set( PROTO_OPT )
|
||||
|
||||
set( EXPORT_FILES
|
||||
${PROTOCOL_NAME}-exp.cnf
|
||||
)
|
||||
|
||||
set( EXT_ASN_FILE_LIST
|
||||
)
|
||||
|
||||
set( ASN_FILE_LIST
|
||||
e2sm-kpm-v2.02.asn
|
||||
e2sm-v3.01.asn
|
||||
)
|
||||
|
||||
set( EXTRA_DIST
|
||||
${ASN_FILE_LIST}
|
||||
packet-${PROTOCOL_NAME}-template.c
|
||||
${PROTOCOL_NAME}.cnf
|
||||
)
|
||||
|
||||
set( SRC_FILES
|
||||
${EXTRA_DIST}
|
||||
${EXT_ASN_FILE_LIST}
|
||||
)
|
||||
|
||||
set( A2W_FLAGS )
|
||||
|
||||
ASN2WRS()
|
|
@ -0,0 +1,384 @@
|
|||
-- ASN1START
|
||||
-- **************************************************************
|
||||
-- E2SM-KPM Information Element Definitions
|
||||
-- **************************************************************
|
||||
|
||||
E2SM-KPM-IEs {
|
||||
iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) oran(53148) e2(1) version2(2) e2sm(2) e2sm-KPMMON-IEs (2)}
|
||||
|
||||
DEFINITIONS AUTOMATIC TAGS ::=
|
||||
|
||||
BEGIN
|
||||
|
||||
-- **************************************************************
|
||||
-- IEs
|
||||
-- **************************************************************
|
||||
|
||||
IMPORTS
|
||||
CGI,
|
||||
FiveQI,
|
||||
PLMNIdentity,
|
||||
QCI,
|
||||
QosFlowIdentifier,
|
||||
RANfunction-Name,
|
||||
RIC-Format-Type,
|
||||
RIC-Style-Name,
|
||||
RIC-Style-Type,
|
||||
S-NSSAI,
|
||||
UEID
|
||||
FROM E2SM-COMMON-IEs;
|
||||
|
||||
TimeStamp ::= OCTET STRING (SIZE(4))
|
||||
|
||||
GranularityPeriod ::= INTEGER (1.. 4294967295)
|
||||
|
||||
MeasurementType ::= CHOICE {
|
||||
measName MeasurementTypeName,
|
||||
measID MeasurementTypeID,
|
||||
...
|
||||
}
|
||||
|
||||
MeasurementTypeName ::= PrintableString(SIZE(1.. 150, ...))
|
||||
|
||||
MeasurementTypeID ::= INTEGER (1.. 65536, ...)
|
||||
|
||||
MeasurementLabel ::= SEQUENCE {
|
||||
noLabel ENUMERATED {true, ...} OPTIONAL,
|
||||
-- TODO: changed from PLMNIdentity and S-NSSAI
|
||||
plmnID PLMNIdentity OPTIONAL,
|
||||
sliceID S-NSSAI OPTIONAL,
|
||||
fiveQI FiveQI OPTIONAL,
|
||||
qFI QosFlowIdentifier OPTIONAL,
|
||||
qCI QCI OPTIONAL,
|
||||
qCImax QCI OPTIONAL,
|
||||
qCImin QCI OPTIONAL,
|
||||
aRPmax INTEGER (1.. 15, ...) OPTIONAL,
|
||||
aRPmin INTEGER (1.. 15, ...) OPTIONAL,
|
||||
bitrateRange INTEGER (1.. 65535, ...) OPTIONAL,
|
||||
layerMU-MIMO INTEGER (1.. 65535, ...) OPTIONAL,
|
||||
sUM ENUMERATED {true, ...} OPTIONAL,
|
||||
distBinX INTEGER (1.. 65535, ...) OPTIONAL,
|
||||
distBinY INTEGER (1.. 65535, ...) OPTIONAL,
|
||||
distBinZ INTEGER (1.. 65535, ...) OPTIONAL,
|
||||
preLabelOverride ENUMERATED {true, ...} OPTIONAL,
|
||||
startEndInd ENUMERATED {start, end, ...} OPTIONAL,
|
||||
min ENUMERATED {true, ...} OPTIONAL,
|
||||
max ENUMERATED {true, ...} OPTIONAL,
|
||||
avg ENUMERATED {true, ...} OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
TestCondInfo ::= SEQUENCE{
|
||||
testType TestCond-Type,
|
||||
testExpr TestCond-Expression OPTIONAL,
|
||||
testValue TestCond-Value OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
TestCond-Type ::= CHOICE{
|
||||
gBR ENUMERATED {true, ...},
|
||||
aMBR ENUMERATED {true, ...},
|
||||
isStat ENUMERATED {true, ...},
|
||||
isCatM ENUMERATED {true, ...},
|
||||
rSRP ENUMERATED {true, ...},
|
||||
rSRQ ENUMERATED {true, ...},
|
||||
...,
|
||||
ul-rSRP ENUMERATED {true, ...},
|
||||
cQI ENUMERATED {true, ...},
|
||||
fiveQI ENUMERATED {true, ...},
|
||||
qCI ENUMERATED {true, ...},
|
||||
sNSSAI ENUMERATED {true, ...}
|
||||
}
|
||||
|
||||
TestCond-Expression ::= ENUMERATED {
|
||||
equal,
|
||||
greaterthan,
|
||||
lessthan,
|
||||
contains,
|
||||
present,
|
||||
...
|
||||
}
|
||||
|
||||
TestCond-Value ::= CHOICE{
|
||||
valueInt INTEGER,
|
||||
valueEnum INTEGER,
|
||||
valueBool BOOLEAN,
|
||||
valueBitS BIT STRING,
|
||||
valueOctS OCTET STRING,
|
||||
valuePrtS PrintableString,
|
||||
...,
|
||||
valueReal REAL
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- **************************************************************
|
||||
-- Lists
|
||||
-- **************************************************************
|
||||
|
||||
maxnoofCells INTEGER ::= 16384
|
||||
maxnoofRICStyles INTEGER ::= 63
|
||||
maxnoofMeasurementInfo INTEGER ::= 65535
|
||||
maxnoofLabelInfo INTEGER ::= 2147483647
|
||||
maxnoofMeasurementRecord INTEGER ::= 65535
|
||||
maxnoofMeasurementValue INTEGER ::= 2147483647
|
||||
maxnoofConditionInfo INTEGER ::= 32768
|
||||
maxnoofUEID INTEGER ::= 65535
|
||||
maxnoofConditionInfoPerSub INTEGER ::= 32768
|
||||
maxnoofUEIDPerSub INTEGER ::= 65535
|
||||
maxnoofUEMeasReport INTEGER ::= 65535
|
||||
|
||||
|
||||
MeasurementInfoList ::= SEQUENCE (SIZE(1..maxnoofMeasurementInfo)) OF MeasurementInfoItem
|
||||
|
||||
MeasurementInfoItem ::= SEQUENCE {
|
||||
measType MeasurementType,
|
||||
labelInfoList LabelInfoList,
|
||||
...
|
||||
}
|
||||
|
||||
LabelInfoList ::= SEQUENCE (SIZE(1..maxnoofLabelInfo)) OF LabelInfoItem
|
||||
|
||||
LabelInfoItem ::= SEQUENCE {
|
||||
measLabel MeasurementLabel,
|
||||
...
|
||||
}
|
||||
|
||||
MeasurementData ::= SEQUENCE (SIZE(1..maxnoofMeasurementRecord)) OF MeasurementDataItem
|
||||
|
||||
MeasurementDataItem ::= SEQUENCE {
|
||||
measRecord MeasurementRecord,
|
||||
incompleteFlag ENUMERATED {true, ...} OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
MeasurementRecord ::= SEQUENCE (SIZE(1..maxnoofMeasurementValue)) OF MeasurementRecordItem
|
||||
|
||||
MeasurementRecordItem ::= CHOICE {
|
||||
integer INTEGER (0.. 4294967295),
|
||||
real REAL,
|
||||
noValue NULL,
|
||||
...
|
||||
}
|
||||
|
||||
MeasurementInfo-Action-List ::= SEQUENCE (SIZE(1..maxnoofMeasurementInfo)) OF MeasurementInfo-Action-Item
|
||||
|
||||
MeasurementInfo-Action-Item ::= SEQUENCE {
|
||||
measName MeasurementTypeName,
|
||||
measID MeasurementTypeID OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
MeasurementCondList ::= SEQUENCE (SIZE(1..maxnoofMeasurementInfo)) OF MeasurementCondItem
|
||||
|
||||
MeasurementCondItem ::= SEQUENCE {
|
||||
measType MeasurementType,
|
||||
matchingCond MatchingCondList,
|
||||
...
|
||||
}
|
||||
|
||||
MeasurementCondUEidList ::= SEQUENCE (SIZE(1..maxnoofMeasurementInfo)) OF MeasurementCondUEidItem
|
||||
|
||||
MeasurementCondUEidItem ::= SEQUENCE {
|
||||
measType MeasurementType,
|
||||
matchingCond MatchingCondList,
|
||||
matchingUEidList MatchingUEidList OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
MatchingCondList ::= SEQUENCE (SIZE(1..maxnoofConditionInfo)) OF MatchingCondItem
|
||||
|
||||
MatchingCondItem ::= CHOICE{
|
||||
measLabel MeasurementLabel,
|
||||
testCondInfo TestCondInfo,
|
||||
...
|
||||
}
|
||||
|
||||
MatchingUEidList ::= SEQUENCE (SIZE(1..maxnoofUEID)) OF MatchingUEidItem
|
||||
|
||||
MatchingUEidItem ::= SEQUENCE{
|
||||
ueID UEID,
|
||||
...
|
||||
}
|
||||
|
||||
MatchingUeCondPerSubList ::= SEQUENCE (SIZE(1..maxnoofConditionInfoPerSub)) OF MatchingUeCondPerSubItem
|
||||
|
||||
MatchingUeCondPerSubItem ::= SEQUENCE{
|
||||
testCondInfo TestCondInfo,
|
||||
...
|
||||
}
|
||||
|
||||
MatchingUEidPerSubList ::= SEQUENCE (SIZE(2..maxnoofUEIDPerSub)) OF MatchingUEidPerSubItem
|
||||
|
||||
MatchingUEidPerSubItem ::= SEQUENCE{
|
||||
ueID UEID,
|
||||
...
|
||||
}
|
||||
|
||||
UEMeasurementReportList ::= SEQUENCE (SIZE(1..maxnoofUEMeasReport)) OF UEMeasurementReportItem
|
||||
|
||||
UEMeasurementReportItem ::= SEQUENCE{
|
||||
ueID UEID,
|
||||
measReport E2SM-KPM-IndicationMessage-Format1,
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- **************************************************************
|
||||
-- E2SM-KPM Service Model IEs
|
||||
-- **************************************************************
|
||||
|
||||
-- **************************************************************
|
||||
-- Event Trigger Definition OCTET STRING contents
|
||||
-- **************************************************************
|
||||
|
||||
E2SM-KPM-EventTriggerDefinition ::= SEQUENCE{
|
||||
eventDefinition-formats CHOICE{
|
||||
eventDefinition-Format1 E2SM-KPM-EventTriggerDefinition-Format1,
|
||||
...
|
||||
},
|
||||
...
|
||||
}
|
||||
|
||||
E2SM-KPM-EventTriggerDefinition-Format1 ::= SEQUENCE{
|
||||
reportingPeriod INTEGER (1.. 4294967295),
|
||||
...
|
||||
}
|
||||
|
||||
-- **************************************************************
|
||||
-- Action Definition OCTET STRING contents
|
||||
-- **************************************************************
|
||||
|
||||
E2SM-KPM-ActionDefinition ::= SEQUENCE{
|
||||
ric-Style-Type RIC-Style-Type,
|
||||
actionDefinition-formats CHOICE{
|
||||
actionDefinition-Format1 E2SM-KPM-ActionDefinition-Format1,
|
||||
actionDefinition-Format2 E2SM-KPM-ActionDefinition-Format2,
|
||||
actionDefinition-Format3 E2SM-KPM-ActionDefinition-Format3,
|
||||
...,
|
||||
actionDefinition-Format4 E2SM-KPM-ActionDefinition-Format4,
|
||||
actionDefinition-Format5 E2SM-KPM-ActionDefinition-Format5
|
||||
},
|
||||
...
|
||||
}
|
||||
|
||||
E2SM-KPM-ActionDefinition-Format1 ::= SEQUENCE {
|
||||
measInfoList MeasurementInfoList,
|
||||
granulPeriod GranularityPeriod,
|
||||
cellGlobalID CGI OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
E2SM-KPM-ActionDefinition-Format2 ::= SEQUENCE {
|
||||
ueID UEID,
|
||||
subscriptInfo E2SM-KPM-ActionDefinition-Format1,
|
||||
...
|
||||
}
|
||||
|
||||
E2SM-KPM-ActionDefinition-Format3 ::= SEQUENCE {
|
||||
measCondList MeasurementCondList,
|
||||
granulPeriod GranularityPeriod,
|
||||
cellGlobalID CGI OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
E2SM-KPM-ActionDefinition-Format4 ::= SEQUENCE {
|
||||
matchingUeCondList MatchingUeCondPerSubList,
|
||||
subscriptionInfo E2SM-KPM-ActionDefinition-Format1,
|
||||
...
|
||||
}
|
||||
|
||||
E2SM-KPM-ActionDefinition-Format5 ::= SEQUENCE {
|
||||
matchingUEidList MatchingUEidPerSubList,
|
||||
subscriptionInfo E2SM-KPM-ActionDefinition-Format1,
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
-- **************************************************************
|
||||
-- Indication Header OCTET STRING contents
|
||||
-- **************************************************************
|
||||
|
||||
E2SM-KPM-IndicationHeader ::= SEQUENCE{
|
||||
indicationHeader-formats CHOICE{
|
||||
indicationHeader-Format1 E2SM-KPM-IndicationHeader-Format1,
|
||||
...
|
||||
},
|
||||
...
|
||||
}
|
||||
|
||||
E2SM-KPM-IndicationHeader-Format1 ::= SEQUENCE{
|
||||
colletStartTime TimeStamp,
|
||||
fileFormatversion PrintableString (SIZE (0..15), ...) OPTIONAL,
|
||||
senderName PrintableString (SIZE (0..400), ...) OPTIONAL,
|
||||
senderType PrintableString (SIZE (0..8), ...) OPTIONAL,
|
||||
vendorName PrintableString (SIZE (0..32), ...) OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
-- **************************************************************
|
||||
-- Indication Message OCTET STRING contents
|
||||
-- **************************************************************
|
||||
|
||||
E2SM-KPM-IndicationMessage ::= SEQUENCE{
|
||||
indicationMessage-formats CHOICE{
|
||||
indicationMessage-Format1 E2SM-KPM-IndicationMessage-Format1,
|
||||
indicationMessage-Format2 E2SM-KPM-IndicationMessage-Format2,
|
||||
...,
|
||||
indicationMessage-Format3 E2SM-KPM-IndicationMessage-Format3
|
||||
},
|
||||
...
|
||||
}
|
||||
|
||||
E2SM-KPM-IndicationMessage-Format1 ::= SEQUENCE {
|
||||
measData MeasurementData,
|
||||
measInfoList MeasurementInfoList OPTIONAL,
|
||||
granulPeriod GranularityPeriod OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
E2SM-KPM-IndicationMessage-Format2 ::= SEQUENCE {
|
||||
measData MeasurementData,
|
||||
measCondUEidList MeasurementCondUEidList,
|
||||
granulPeriod GranularityPeriod OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
E2SM-KPM-IndicationMessage-Format3 ::= SEQUENCE {
|
||||
ueMeasReportList UEMeasurementReportList,
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
-- ***************************************************************
|
||||
-- RAN Function Definition OCTET STRING contents
|
||||
-- ***************************************************************
|
||||
|
||||
E2SM-KPM-RANfunction-Description ::= SEQUENCE{
|
||||
ranFunction-Name RANfunction-Name,
|
||||
ric-EventTriggerStyle-List SEQUENCE (SIZE(1..maxnoofRICStyles)) OF RIC-EventTriggerStyle-Item OPTIONAL,
|
||||
ric-ReportStyle-List SEQUENCE (SIZE(1..maxnoofRICStyles)) OF RIC-ReportStyle-Item OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
RIC-EventTriggerStyle-Item ::= SEQUENCE{
|
||||
ric-EventTriggerStyle-Type RIC-Style-Type,
|
||||
ric-EventTriggerStyle-Name RIC-Style-Name,
|
||||
ric-EventTriggerFormat-Type RIC-Format-Type,
|
||||
...
|
||||
}
|
||||
|
||||
RIC-ReportStyle-Item ::= SEQUENCE{
|
||||
ric-ReportStyle-Type RIC-Style-Type,
|
||||
ric-ReportStyle-Name RIC-Style-Name,
|
||||
ric-ActionFormat-Type RIC-Format-Type,
|
||||
measInfo-Action-List MeasurementInfo-Action-List,
|
||||
ric-IndicationHeaderFormat-Type RIC-Format-Type,
|
||||
ric-IndicationMessageFormat-Type RIC-Format-Type,
|
||||
...
|
||||
}
|
||||
|
||||
END
|
||||
|
||||
-- ASN1STOP
|
|
@ -0,0 +1,388 @@
|
|||
-- ASN1START
|
||||
-- **************************************************************
|
||||
-- E2SM
|
||||
-- Information Element Definitions
|
||||
-- N.B. this is an edited version, only supplying what is needed for KPM-v2
|
||||
-- **************************************************************
|
||||
|
||||
E2SM-COMMON-IEs {
|
||||
iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) 53148 e2(1) version1 (1) e2sm(2) e2sm-COMMON-IEs (0)}
|
||||
|
||||
DEFINITIONS AUTOMATIC TAGS ::=
|
||||
|
||||
BEGIN
|
||||
|
||||
-- --------------------------------------------------
|
||||
-- Constants
|
||||
-- --------------------------------------------------
|
||||
|
||||
maxE1APid INTEGER ::= 65535
|
||||
maxF1APid INTEGER ::= 4
|
||||
|
||||
-- IEs derived from 3GPP 36.423 (X2AP)
|
||||
maxEARFCN INTEGER ::= 65535
|
||||
|
||||
-- IEs derived from 3GPP 38.473 (F1AP)
|
||||
maxNRARFCN INTEGER ::= 3279165
|
||||
maxnoofNrCellBands INTEGER ::= 32
|
||||
|
||||
|
||||
-- --------------------------------------------------
|
||||
-- E2SM Commmon IEs
|
||||
-- --------------------------------------------------
|
||||
|
||||
CGI ::= CHOICE {
|
||||
nR-CGI NR-CGI,
|
||||
eUTRA-CGI EUTRA-CGI,
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
RANfunction-Name ::= SEQUENCE{
|
||||
ranFunction-ShortName PrintableString(SIZE(1..150,...)),
|
||||
ranFunction-E2SM-OID PrintableString(SIZE(1..1000,...)),
|
||||
ranFunction-Description PrintableString(SIZE(1..150,...)),
|
||||
ranFunction-Instance INTEGER OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
RIC-Format-Type ::= INTEGER
|
||||
|
||||
RIC-Style-Type ::= INTEGER
|
||||
|
||||
RIC-Style-Name ::= PrintableString(SIZE(1..150,...))
|
||||
|
||||
UEID ::= CHOICE{
|
||||
gNB-UEID UEID-GNB,
|
||||
gNB-DU-UEID UEID-GNB-DU,
|
||||
gNB-CU-UP-UEID UEID-GNB-CU-UP,
|
||||
ng-eNB-UEID UEID-NG-ENB,
|
||||
ng-eNB-DU-UEID UEID-NG-ENB-DU,
|
||||
en-gNB-UEID UEID-EN-GNB,
|
||||
eNB-UEID UEID-ENB,
|
||||
...
|
||||
}
|
||||
|
||||
UEID-GNB ::= SEQUENCE{
|
||||
amf-UE-NGAP-ID AMF-UE-NGAP-ID,
|
||||
guami GUAMI,
|
||||
gNB-CU-UE-F1AP-ID-List UEID-GNB-CU-F1AP-ID-List OPTIONAL,
|
||||
-- C-ifCUDUseparated: This IE shall be present in messages from E2 Node to NearRT-RIC for a CU-DU separated gNB, whereas from NearRT-RIC to E2 Node messages, this IE may not be included. More than 1 F1AP ID shall be reported by E2 Node only when NR-DC is established.
|
||||
gNB-CU-CP-UE-E1AP-ID-List UEID-GNB-CU-CP-E1AP-ID-List OPTIONAL,
|
||||
-- C-ifCPUPseparated: This IE shall be present in messages from E2 Node to NearRT-RIC for a CP-UP separated gNB, whereas from NearRT-RIC to E2 Node messages, this IE may not be included.
|
||||
ran-UEID RANUEID OPTIONAL,
|
||||
m-NG-RAN-UE-XnAP-ID NG-RANnodeUEXnAPID OPTIONAL,
|
||||
-- C-ifDCSetup: This IE shall be present in messages from E2 Node to NearRT-RIC if DC is established, whereas from NearRT-RIC to E2 Node messages, this IE may not be included. To be reported by both MN and SN.
|
||||
globalGNB-ID GlobalGNB-ID OPTIONAL,
|
||||
-- This IE shall not be used. This IE is replaced with globalNG-RANNode-ID.
|
||||
...,
|
||||
globalNG-RANNode-ID GlobalNGRANNodeID OPTIONAL
|
||||
-- C-ifDCSetup: This IE shall be present in messages from E2 Node to NearRT-RIC if DC is established, whereas from NearRT-RIC to E2 Node messages, this IE may not be included. To be reported only by SN.
|
||||
}
|
||||
|
||||
UEID-GNB-CU-CP-E1AP-ID-List ::= SEQUENCE (SIZE(1..maxE1APid)) OF UEID-GNB-CU-CP-E1AP-ID-Item
|
||||
|
||||
UEID-GNB-CU-CP-E1AP-ID-Item ::= SEQUENCE{
|
||||
gNB-CU-CP-UE-E1AP-ID GNB-CU-CP-UE-E1AP-ID,
|
||||
...
|
||||
}
|
||||
|
||||
UEID-GNB-CU-F1AP-ID-List ::= SEQUENCE (SIZE(1..maxF1APid)) OF UEID-GNB-CU-CP-F1AP-ID-Item
|
||||
|
||||
UEID-GNB-CU-CP-F1AP-ID-Item ::= SEQUENCE{
|
||||
gNB-CU-UE-F1AP-ID GNB-CU-UE-F1AP-ID,
|
||||
...
|
||||
}
|
||||
|
||||
UEID-GNB-DU ::= SEQUENCE{
|
||||
gNB-CU-UE-F1AP-ID GNB-CU-UE-F1AP-ID,
|
||||
ran-UEID RANUEID OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
UEID-GNB-CU-UP ::= SEQUENCE{
|
||||
gNB-CU-CP-UE-E1AP-ID GNB-CU-CP-UE-E1AP-ID,
|
||||
ran-UEID RANUEID OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
UEID-NG-ENB ::= SEQUENCE{
|
||||
amf-UE-NGAP-ID AMF-UE-NGAP-ID,
|
||||
guami GUAMI,
|
||||
ng-eNB-CU-UE-W1AP-ID NGENB-CU-UE-W1AP-ID OPTIONAL,
|
||||
-- C-ifCUDUseperated: This IE shall be present in messages from E2 Node to NearRT-RIC for a CU-DU seperated ng-eNB, whereas from NearRT-RIC to E2 Node messages, this IE may not be included.
|
||||
m-NG-RAN-UE-XnAP-ID NG-RANnodeUEXnAPID OPTIONAL,
|
||||
-- C-ifDCSetup: This IE shall be present in messages from E2 Node to NearRT-RIC if DC is established, whereas from NearRT-RIC to E2 Node messages, this IE may not be included. To be reported by both MN and SN.
|
||||
globalNgENB-ID GlobalNgENB-ID OPTIONAL,
|
||||
-- This IE shall not be used. This IE is replaced with globalNG-RANNode-ID.
|
||||
...,
|
||||
globalNG-RANNode-ID GlobalNGRANNodeID OPTIONAL
|
||||
-- C-ifDCSetup: This IE shall be present in messages from E2 Node to NearRT-RIC if DC is established, whereas from NearRT-RIC to E2 Node messages, this IE may not be included. To be reported only by SN.
|
||||
}
|
||||
|
||||
|
||||
UEID-NG-ENB-DU ::= SEQUENCE{
|
||||
ng-eNB-CU-UE-W1AP-ID NGENB-CU-UE-W1AP-ID,
|
||||
...
|
||||
}
|
||||
|
||||
UEID-EN-GNB ::= SEQUENCE{
|
||||
m-eNB-UE-X2AP-ID ENB-UE-X2AP-ID,
|
||||
m-eNB-UE-X2AP-ID-Extension ENB-UE-X2AP-ID-Extension OPTIONAL,
|
||||
globalENB-ID GlobalENB-ID,
|
||||
gNB-CU-UE-F1AP-ID GNB-CU-UE-F1AP-ID OPTIONAL,
|
||||
-- C-ifCUDUseperated: This IE shall be present in messages from E2 Node to NearRT-RIC for a CU-DU seperated en-gNB, whereas from NearRT-RIC to E2 Node messages, this IE may not be included.
|
||||
gNB-CU-CP-UE-E1AP-ID-List UEID-GNB-CU-CP-E1AP-ID-List OPTIONAL,
|
||||
-- C-ifCPUPseparated: This IE shall be present in messages from E2 Node to NearRT-RIC for a CP-UP separated en-gNB, whereas from NearRT-RIC to E2 Node messages, this IE may not be included.
|
||||
ran-UEID RANUEID OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
UEID-ENB ::= SEQUENCE{
|
||||
mME-UE-S1AP-ID MME-UE-S1AP-ID,
|
||||
gUMMEI GUMMEI,
|
||||
m-eNB-UE-X2AP-ID ENB-UE-X2AP-ID OPTIONAL,
|
||||
-- This IE shall be present in messages from E2 Node to NearRT-RIC if DC is established, whereas from NearRT-RIC to E2 Node messages, this IE may not be included. To be reported by MeNB and SeNB.
|
||||
m-eNB-UE-X2AP-ID-Extension ENB-UE-X2AP-ID-Extension OPTIONAL,
|
||||
globalENB-ID GlobalENB-ID OPTIONAL,
|
||||
-- This IE shall be present in messages from E2 Node to NearRT-RIC if DC is established, whereas from NearRT-RIC to E2 Node messages, this IE may not be included. To be reported only by SeNB.
|
||||
...
|
||||
}
|
||||
|
||||
-- **************************************************************
|
||||
-- 3GPP derived IEs
|
||||
-- **************************************************************
|
||||
-- NOTE:
|
||||
-- - Extension fields removed and replaced with "..."
|
||||
-- - IE names modified across all extracts to use "PLMNIdentity"
|
||||
|
||||
-- **************************************************************
|
||||
-- IEs derived from 3GPP 36.413 (S1AP)
|
||||
-- **************************************************************
|
||||
-- **************************************************************
|
||||
|
||||
-- copied from v16.5.0
|
||||
ENB-ID ::= CHOICE {
|
||||
macro-eNB-ID BIT STRING (SIZE (20)),
|
||||
home-eNB-ID BIT STRING (SIZE (28)),
|
||||
... ,
|
||||
short-Macro-eNB-ID BIT STRING (SIZE(18)),
|
||||
long-Macro-eNB-ID BIT STRING (SIZE(21))
|
||||
}
|
||||
|
||||
-- copied from v16.5.0
|
||||
GlobalENB-ID ::= SEQUENCE {
|
||||
pLMNIdentity PLMNIdentity,
|
||||
eNB-ID ENB-ID,
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
-- copied from v16.5.0
|
||||
GUMMEI ::= SEQUENCE {
|
||||
pLMN-Identity PLMNIdentity,
|
||||
mME-Group-ID MME-Group-ID,
|
||||
mME-Code MME-Code,
|
||||
...
|
||||
}
|
||||
|
||||
-- copied from v16.5.0
|
||||
MME-Group-ID ::= OCTET STRING (SIZE (2))
|
||||
|
||||
-- copied from v16.5.0
|
||||
MME-Code ::= OCTET STRING (SIZE (1))
|
||||
|
||||
-- copied from v16.5.0
|
||||
MME-UE-S1AP-ID ::= INTEGER (0..4294967295)
|
||||
|
||||
-- copied from v16.5.0
|
||||
QCI ::= INTEGER (0..255)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- **************************************************************
|
||||
-- IEs derived from 3GPP 36.423 (X2AP)
|
||||
-- **************************************************************
|
||||
-- Extension fields removed.
|
||||
-- Note: to avoid duplicate names with NGAP, XnAP, etc.:
|
||||
-- GNB-ID renamed ENGNB-ID,
|
||||
-- GlobalGNB-ID renamed GlobalenGNB-ID,
|
||||
-- UE-X2AP-ID renamed ENB-UE-X2AP-ID
|
||||
-- UE-X2AP-ID-Extension renamed ENB-UE-X2AP-ID-Extension
|
||||
-- **************************************************************
|
||||
|
||||
|
||||
-- copied from v16.5.0
|
||||
ENB-UE-X2AP-ID ::= INTEGER (0..4095)
|
||||
|
||||
-- copied from v16.5.0
|
||||
ENB-UE-X2AP-ID-Extension ::= INTEGER (0..4095, ...)
|
||||
|
||||
|
||||
|
||||
|
||||
-- **************************************************************
|
||||
-- IEs derived from 3GPP 37.473 (W1AP)
|
||||
-- **************************************************************
|
||||
|
||||
-- copied from v16.3.0
|
||||
NGENB-CU-UE-W1AP-ID ::= INTEGER (0..4294967295)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- **************************************************************
|
||||
-- IEs derived from 3GPP 38.413 (NGAP)
|
||||
-- Extension fields removed and replaced with ...
|
||||
-- **************************************************************
|
||||
|
||||
-- copied from v16.2.0
|
||||
AMFPointer ::= BIT STRING (SIZE(6))
|
||||
|
||||
-- copied from v16.2.0
|
||||
AMFRegionID ::= BIT STRING (SIZE(8))
|
||||
|
||||
-- copied from v16.2.0
|
||||
AMFSetID ::= BIT STRING (SIZE(10))
|
||||
|
||||
-- copied from v16.2.0
|
||||
AMF-UE-NGAP-ID ::= INTEGER (0..1099511627775)
|
||||
|
||||
-- copied from v16.2.0
|
||||
EUTRACellIdentity ::= BIT STRING (SIZE(28))
|
||||
|
||||
-- copied from v16.2.0
|
||||
EUTRA-CGI ::= SEQUENCE {
|
||||
pLMNIdentity PLMNIdentity,
|
||||
eUTRACellIdentity EUTRACellIdentity,
|
||||
...
|
||||
}
|
||||
|
||||
-- copied from v16.2.0
|
||||
FiveQI ::= INTEGER (0..255, ...)
|
||||
|
||||
-- copied from v16.2.0
|
||||
GlobalGNB-ID ::= SEQUENCE {
|
||||
pLMNIdentity PLMNIdentity,
|
||||
gNB-ID GNB-ID,
|
||||
...
|
||||
}
|
||||
|
||||
-- copied from v16.2.0
|
||||
GlobalNgENB-ID ::= SEQUENCE {
|
||||
pLMNIdentity PLMNIdentity,
|
||||
ngENB-ID NgENB-ID,
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
-- copied from v16.2.0
|
||||
GNB-ID ::= CHOICE {
|
||||
gNB-ID BIT STRING (SIZE(22..32)),
|
||||
...
|
||||
}
|
||||
|
||||
-- copied from v16.2.0
|
||||
GUAMI ::= SEQUENCE {
|
||||
pLMNIdentity PLMNIdentity,
|
||||
aMFRegionID AMFRegionID,
|
||||
aMFSetID AMFSetID,
|
||||
aMFPointer AMFPointer,
|
||||
...
|
||||
}
|
||||
|
||||
-- copied from v16.2.0
|
||||
NgENB-ID ::= CHOICE {
|
||||
macroNgENB-ID BIT STRING (SIZE(20)),
|
||||
shortMacroNgENB-ID BIT STRING (SIZE(18)),
|
||||
longMacroNgENB-ID BIT STRING (SIZE(21)),
|
||||
...
|
||||
}
|
||||
|
||||
-- copied from v16.2.0
|
||||
NRCellIdentity ::= BIT STRING (SIZE(36))
|
||||
|
||||
-- copied from v16.2.0
|
||||
NR-CGI ::= SEQUENCE {
|
||||
pLMNIdentity PLMNIdentity,
|
||||
nRCellIdentity NRCellIdentity,
|
||||
...
|
||||
}
|
||||
|
||||
-- copied from v16.2.0
|
||||
PLMNIdentity ::= OCTET STRING (SIZE(3))
|
||||
|
||||
-- copied from v16.2.0
|
||||
QosFlowIdentifier ::= INTEGER (0..63, ...)
|
||||
|
||||
-- copied from v16.2.0
|
||||
SD ::= OCTET STRING (SIZE(3))
|
||||
|
||||
-- copied from v16.2.0
|
||||
S-NSSAI ::= SEQUENCE {
|
||||
sST SST,
|
||||
sD SD OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
-- copied from v16.2.0
|
||||
SST ::= OCTET STRING (SIZE(1))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- **************************************************************
|
||||
-- IEs derived from 3GPP 38.423 (XnAP)
|
||||
-- **************************************************************
|
||||
|
||||
-- copied from v16.2.0
|
||||
NG-RANnodeUEXnAPID ::= INTEGER (0.. 4294967295)
|
||||
|
||||
GlobalNGRANNodeID ::= CHOICE {
|
||||
gNB GlobalGNB-ID,
|
||||
ng-eNB GlobalNgENB-ID,
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
-- **************************************************************
|
||||
-- IEs derived from 3GPP 37.483 (E1AP)
|
||||
-- **************************************************************
|
||||
|
||||
-- copied from v17.1.0
|
||||
GNB-CU-CP-UE-E1AP-ID ::= INTEGER (0..4294967295)
|
||||
|
||||
-- copied from v17.1.0
|
||||
-- GNB-CU-UP-ID ::= INTEGER (0..68719476735)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- **************************************************************
|
||||
-- IEs derived from 3GPP 38.473 (F1AP)
|
||||
-- **************************************************************
|
||||
|
||||
|
||||
|
||||
-- copied from v16.5.0
|
||||
GNB-CU-UE-F1AP-ID ::= INTEGER (0..4294967295)
|
||||
|
||||
|
||||
|
||||
-- copied from v16.5.0
|
||||
RANUEID ::= OCTET STRING (SIZE (8))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
END
|
||||
-- ASN1STOP
|
|
@ -0,0 +1,77 @@
|
|||
# kpm-v2.cnf
|
||||
# kpm-v2 conformation file
|
||||
|
||||
#.OPT
|
||||
PER
|
||||
ALIGNED
|
||||
#.END
|
||||
|
||||
#.USE_VALS_EXT
|
||||
|
||||
#.EXPORTS ONLY_VALS WS_DLL
|
||||
|
||||
#.EXPORTS
|
||||
|
||||
#.PDU
|
||||
|
||||
E2SM-KPM-EventTriggerDefinition
|
||||
E2SM-KPM-ActionDefinition
|
||||
E2SM-KPM-IndicationHeader
|
||||
E2SM-KPM-IndicationMessage
|
||||
E2SM-KPM-RANfunction-Description
|
||||
|
||||
|
||||
#.MAKE_ENUM
|
||||
|
||||
#.NO_EMIT
|
||||
|
||||
#.OMIT_ASSIGNMENT
|
||||
|
||||
#.END
|
||||
|
||||
|
||||
#.TYPE_ATTR
|
||||
|
||||
#.TYPE_RENAME
|
||||
|
||||
#.FIELD_RENAME
|
||||
|
||||
#.FIELD_ATTR
|
||||
|
||||
#.ASSIGN_VALUE_TO_TYPE
|
||||
|
||||
#.END
|
||||
|
||||
#.REGISTER
|
||||
|
||||
#.FN_BODY RANfunction-Name/ranFunction-ShortName VAL_PTR=&value_tvb
|
||||
tvbuff_t *value_tvb;
|
||||
%(DEFAULT_BODY)s
|
||||
if (!actx->pinfo->fd->visited) {
|
||||
/* N.B. too early to work out exact dissector, as don't have OID yet */
|
||||
e2ap_store_ran_function_mapping(actx->pinfo,
|
||||
tvb_get_string_enc(wmem_packet_scope(), value_tvb, 0, tvb_captured_length(value_tvb), ENC_ASCII));
|
||||
}
|
||||
|
||||
|
||||
#.FN_BODY RANfunction-Name/ranFunction-E2SM-OID VAL_PTR = ¶meter_tvb
|
||||
tvbuff_t *parameter_tvb;
|
||||
%(DEFAULT_BODY)s
|
||||
e2ap_update_ran_function_mapping(actx->pinfo, tree, parameter_tvb,
|
||||
tvb_get_string_enc(actx->pinfo->pool, parameter_tvb, 0,
|
||||
tvb_captured_length(parameter_tvb), ENC_ASCII));
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
#
|
||||
# Local variables:
|
||||
# c-basic-offset: 2
|
||||
# tab-width: 8
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vi: set shiftwidth=2 tabstop=8 expandtab:
|
||||
# :indentSize=2:tabSize=8:noTabs=true:
|
||||
#
|
|
@ -0,0 +1,114 @@
|
|||
/* packet-kpm-v2-template.c
|
||||
* Copyright 2021, Martin Mathieson
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*
|
||||
* References: ORAN-WG3.E2SM-KPM-v02.02
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <epan/packet.h>
|
||||
#include <epan/strutil.h>
|
||||
#include <epan/asn1.h>
|
||||
|
||||
#include "packet-e2ap.h"
|
||||
#include "packet-per.h"
|
||||
#define PNAME "KPM V2"
|
||||
#define PSNAME "KPMv2"
|
||||
#define PFNAME "kpm-v2"
|
||||
|
||||
|
||||
void proto_register_kpm_v2(void);
|
||||
void proto_reg_handoff_kpm_v2(void);
|
||||
|
||||
|
||||
#include "packet-kpm-v2-val.h"
|
||||
|
||||
/* Initialize the protocol and registered fields */
|
||||
static int proto_kpm_v2 = -1;
|
||||
#include "packet-kpm-v2-hf.c"
|
||||
|
||||
|
||||
#include "packet-kpm-v2-ett.c"
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
static int dissect_E2SM_KPM_EventTriggerDefinition_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
static int dissect_E2SM_KPM_ActionDefinition_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
static int dissect_E2SM_KPM_IndicationHeader_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
static int dissect_E2SM_KPM_IndicationMessage_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
static int dissect_E2SM_KPM_RANfunction_Description_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
|
||||
|
||||
#include "packet-kpm-v2-fn.c"
|
||||
|
||||
|
||||
/*--- proto_reg_handoff_kpm_v2 ---------------------------------------*/
|
||||
void
|
||||
proto_reg_handoff_kpm_v2(void)
|
||||
{
|
||||
//#include "packet-kpm-v2-dis-tab.c"
|
||||
|
||||
static ran_function_dissector_t kpm_v2 =
|
||||
{ "ORAN-E2SM-KPM", "1.3.6.1.4.1.53148.1.2.2.2", 2, 2,
|
||||
{ dissect_E2SM_KPM_RANfunction_Description_PDU,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
dissect_E2SM_KPM_ActionDefinition_PDU,
|
||||
dissect_E2SM_KPM_IndicationMessage_PDU,
|
||||
dissect_E2SM_KPM_IndicationHeader_PDU,
|
||||
NULL, /* no dissect_E2SM_KPM_CallProcessID_PDU */
|
||||
dissect_E2SM_KPM_EventTriggerDefinition_PDU
|
||||
}
|
||||
};
|
||||
|
||||
/* Register dissector with e2ap */
|
||||
register_e2ap_ran_function_dissector(KPM_RANFUNCTIONS, &kpm_v2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*--- proto_register_kpm_v2 -------------------------------------------*/
|
||||
void proto_register_kpm_v2(void) {
|
||||
|
||||
/* List of fields */
|
||||
|
||||
static hf_register_info hf[] = {
|
||||
#include "packet-kpm-v2-hfarr.c"
|
||||
};
|
||||
|
||||
/* List of subtrees */
|
||||
static gint *ett[] = {
|
||||
#include "packet-kpm-v2-ettarr.c"
|
||||
};
|
||||
|
||||
|
||||
/* Register protocol */
|
||||
proto_kpm_v2 = proto_register_protocol(PNAME, PSNAME, PFNAME);
|
||||
/* Register fields and subtrees */
|
||||
proto_register_field_array(proto_kpm_v2, hf, array_length(hf));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines
|
||||
*
|
||||
* Local Variables:
|
||||
* c-basic-offset: 2
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* ex: set shiftwidth=2 tabstop=8 expandtab:
|
||||
* :indentSize=2:tabSize=8:noTabs=true:
|
||||
*/
|
File diff suppressed because it is too large
Load Diff
|
@ -26,6 +26,51 @@
|
|||
/*--- End of included file: packet-e2ap-exp.h ---*/
|
||||
#line 15 "./asn1/e2ap/packet-e2ap-template.h"
|
||||
|
||||
typedef int (*pdu_dissector_t)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data);
|
||||
|
||||
/* Function pointers for a RANFunction */
|
||||
typedef struct {
|
||||
pdu_dissector_t ran_function_definition_dissector;
|
||||
|
||||
pdu_dissector_t ric_control_header_dissector;
|
||||
pdu_dissector_t ric_control_message_dissector;
|
||||
pdu_dissector_t ric_control_outcome_dissector;
|
||||
/* new for v3 */
|
||||
pdu_dissector_t ric_query_outcome_dissector;
|
||||
pdu_dissector_t ric_query_definition_dissector;
|
||||
pdu_dissector_t ric_query_header_dissector;
|
||||
|
||||
pdu_dissector_t ran_action_definition_dissector;
|
||||
pdu_dissector_t ran_indication_message_dissector;
|
||||
pdu_dissector_t ran_indication_header_dissector;
|
||||
pdu_dissector_t ran_callprocessid_dissector;
|
||||
pdu_dissector_t ran_event_trigger_dissector;
|
||||
} ran_function_pointers_t;
|
||||
|
||||
typedef enum {
|
||||
MIN_RANFUNCTIONS,
|
||||
KPM_RANFUNCTIONS=0,
|
||||
RC_RANFUNCTIONS,
|
||||
NI_RANFUNCTIONS,
|
||||
MAX_RANFUNCTIONS
|
||||
} ran_function_t;
|
||||
|
||||
#define MAX_OID_LEN 1001
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
char oid[MAX_OID_LEN]; /* i.e., this dissector */
|
||||
uint8_t major_version;
|
||||
uint8_t minor_version;
|
||||
ran_function_pointers_t functions;
|
||||
} ran_function_dissector_t;
|
||||
|
||||
void register_e2ap_ran_function_dissector(ran_function_t ran_function, ran_function_dissector_t *dissector);
|
||||
|
||||
void e2ap_store_ran_function_mapping(packet_info *pinfo, const char *name);
|
||||
void e2ap_update_ran_function_mapping(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, const char *oid);
|
||||
|
||||
|
||||
#endif /* PACKET_E2AP_H */
|
||||
|
||||
/*
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -899,6 +899,7 @@ char* rel_oid_subid2string(wmem_allocator_t *scope, guint32* subids, guint len,
|
|||
return wmem_strbuf_finalize(oid_str);
|
||||
}
|
||||
|
||||
/* If a valid OID string, return number of numbers */
|
||||
static guint check_num_oid(const char* str) {
|
||||
const char* r = str;
|
||||
char c = '.';
|
||||
|
@ -925,6 +926,7 @@ static guint check_num_oid(const char* str) {
|
|||
return n;
|
||||
}
|
||||
|
||||
/* Set subids_p to an array of found numbers, return number of numbers */
|
||||
guint oid_string2subid(wmem_allocator_t *scope, const char* str, guint32** subids_p) {
|
||||
const char* r = str;
|
||||
guint32* subids;
|
||||
|
|
Loading…
Reference in New Issue