/* THIS FILE IS GENERATED FROM gtlv_gen.c */
#include <stddef.h>
#include <errno.h>
#include <osmocom/core/utils.h>
#include <osmocom/gtlv/gtlv.h>
#include <osmocom/gtlv/gtlv_dec_enc.h>
#include <osmocom/gtlv/gtlv_gen.h>

#include <osmocom/pfcp/pfcp_ies_auto.h>

extern int osmo_pfcp_dec_32be(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_32be(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_32be(char *buf, size_t buflen, const void *encode_from);
extern int osmo_pfcp_dec_node_id(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_node_id(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_node_id(char *buf, size_t buflen, const void *encode_from);
extern int osmo_pfcp_dec_up_function_features(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_up_function_features(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_up_function_features(char *buf, size_t buflen, const void *encode_from);
extern int osmo_pfcp_dec_cp_function_features(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_cp_function_features(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_cp_function_features(char *buf, size_t buflen, const void *encode_from);
extern int osmo_pfcp_dec_cause(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_cause(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_cause(char *buf, size_t buflen, const void *encode_from);
extern int osmo_pfcp_dec_f_seid(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_f_seid(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_f_seid(char *buf, size_t buflen, const void *encode_from);
extern int osmo_pfcp_dec_16be(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_16be(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_16be(char *buf, size_t buflen, const void *encode_from);
extern int osmo_pfcp_dec_source_iface(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_source_iface(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_source_iface(char *buf, size_t buflen, const void *encode_from);
extern int osmo_pfcp_dec_f_teid(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_f_teid(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_f_teid(char *buf, size_t buflen, const void *encode_from);
extern int osmo_pfcp_dec_network_inst(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_network_inst(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_network_inst(char *buf, size_t buflen, const void *encode_from);
extern int osmo_pfcp_dec_ue_ip_address(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_ue_ip_address(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_ue_ip_address(char *buf, size_t buflen, const void *encode_from);
extern int osmo_pfcp_dec_8(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_8(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_8(char *buf, size_t buflen, const void *encode_from);
extern int osmo_pfcp_dec_3gpp_iface_type(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_3gpp_iface_type(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_3gpp_iface_type(char *buf, size_t buflen, const void *encode_from);
extern int osmo_pfcp_dec_outer_header_removal(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_outer_header_removal(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_outer_header_removal(char *buf, size_t buflen, const void *encode_from);
extern int osmo_pfcp_dec_activate_predefined_rules(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_activate_predefined_rules(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_activate_predefined_rules(char *buf, size_t buflen, const void *encode_from);
extern int osmo_pfcp_dec_apply_action(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_apply_action(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_apply_action(char *buf, size_t buflen, const void *encode_from);
extern int osmo_pfcp_dec_dest_iface(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_dest_iface(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_dest_iface(char *buf, size_t buflen, const void *encode_from);
extern int osmo_pfcp_dec_outer_header_creation(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_outer_header_creation(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_outer_header_creation(char *buf, size_t buflen, const void *encode_from);
extern int osmo_pfcp_dec_offending_ie(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *gtlv);
extern int osmo_pfcp_enc_offending_ie(struct osmo_gtlv_put *gtlv, const void *decoded_struct, const void *encode_from);
extern int osmo_pfcp_enc_to_str_offending_ie(char *buf, size_t buflen, const void *encode_from);

static const struct osmo_gtlv_coding ies_in_pdi[] = {
	{ { OSMO_PFCP_IEI_SOURCE_IFACE },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_pdi, source_iface),
	  .dec_func = osmo_pfcp_dec_source_iface,
	  .enc_func = osmo_pfcp_enc_source_iface,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_source_iface,
	},
	{ { OSMO_PFCP_IEI_F_TEID },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_pdi, local_f_teid),
	  .dec_func = osmo_pfcp_dec_f_teid,
	  .enc_func = osmo_pfcp_enc_f_teid,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_f_teid,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_pdi, local_f_teid_present),
	},
	{ { OSMO_PFCP_IEI_NETWORK_INST },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_pdi, network_inst),
	  .dec_func = osmo_pfcp_dec_network_inst,
	  .enc_func = osmo_pfcp_enc_network_inst,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_network_inst,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_pdi, network_inst_present),
	},
	{ { OSMO_PFCP_IEI_UE_IP_ADDRESS },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_pdi, ue_ip_address),
	  .dec_func = osmo_pfcp_dec_ue_ip_address,
	  .enc_func = osmo_pfcp_enc_ue_ip_address,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_ue_ip_address,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_pdi, ue_ip_address_present),
	},
	{ { OSMO_PFCP_IEI_TRAFFIC_ENDPOINT_ID },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_pdi, traffic_endpoint_id),
	  .dec_func = osmo_pfcp_dec_8,
	  .enc_func = osmo_pfcp_enc_8,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_8,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_pdi, traffic_endpoint_id_present),
	},
	{ { OSMO_PFCP_IEI_3GPP_IFACE_TYPE },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_pdi, source_iface_type),
	  .dec_func = osmo_pfcp_dec_3gpp_iface_type,
	  .enc_func = osmo_pfcp_enc_3gpp_iface_type,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_3gpp_iface_type,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_pdi, source_iface_type_present),
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_create_pdr[] = {
	{ { OSMO_PFCP_IEI_PDR_ID },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_create_pdr, pdr_id),
	  .dec_func = osmo_pfcp_dec_16be,
	  .enc_func = osmo_pfcp_enc_16be,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_16be,
	},
	{ { OSMO_PFCP_IEI_PRECEDENCE },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_create_pdr, precedence),
	  .dec_func = osmo_pfcp_dec_32be,
	  .enc_func = osmo_pfcp_enc_32be,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_32be,
	},
	{ { OSMO_PFCP_IEI_PDI },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_create_pdr, pdi),
	  .nested_ies = ies_in_pdi,
	},
	{ { OSMO_PFCP_IEI_OUTER_HEADER_REMOVAL },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_create_pdr, outer_header_removal),
	  .dec_func = osmo_pfcp_dec_outer_header_removal,
	  .enc_func = osmo_pfcp_enc_outer_header_removal,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_outer_header_removal,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_create_pdr, outer_header_removal_present),
	},
	{ { OSMO_PFCP_IEI_FAR_ID },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_create_pdr, far_id),
	  .dec_func = osmo_pfcp_dec_32be,
	  .enc_func = osmo_pfcp_enc_32be,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_32be,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_create_pdr, far_id_present),
	},
	{ { OSMO_PFCP_IEI_ACTIVATE_PREDEFINED_RULES },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_create_pdr, activate_predefined_rules),
	  .dec_func = osmo_pfcp_dec_activate_predefined_rules,
	  .enc_func = osmo_pfcp_enc_activate_predefined_rules,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_activate_predefined_rules,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_create_pdr, activate_predefined_rules_present),
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_forw_params[] = {
	{ { OSMO_PFCP_IEI_DESTINATION_IFACE },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_forw_params, destination_iface),
	  .dec_func = osmo_pfcp_dec_dest_iface,
	  .enc_func = osmo_pfcp_enc_dest_iface,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_dest_iface,
	},
	{ { OSMO_PFCP_IEI_NETWORK_INST },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_forw_params, network_inst),
	  .dec_func = osmo_pfcp_dec_network_inst,
	  .enc_func = osmo_pfcp_enc_network_inst,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_network_inst,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_forw_params, network_inst_present),
	},
	{ { OSMO_PFCP_IEI_OUTER_HEADER_CREATION },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_forw_params, outer_header_creation),
	  .dec_func = osmo_pfcp_dec_outer_header_creation,
	  .enc_func = osmo_pfcp_enc_outer_header_creation,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_outer_header_creation,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_forw_params, outer_header_creation_present),
	},
	{ { OSMO_PFCP_IEI_TRAFFIC_ENDPOINT_ID },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_forw_params, linked_te_id),
	  .dec_func = osmo_pfcp_dec_8,
	  .enc_func = osmo_pfcp_enc_8,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_8,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_forw_params, linked_te_id_present),
	},
	{ { OSMO_PFCP_IEI_3GPP_IFACE_TYPE },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_forw_params, destination_iface_type),
	  .dec_func = osmo_pfcp_dec_3gpp_iface_type,
	  .enc_func = osmo_pfcp_enc_3gpp_iface_type,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_3gpp_iface_type,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_forw_params, destination_iface_type_present),
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_create_far[] = {
	{ { OSMO_PFCP_IEI_FAR_ID },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_create_far, far_id),
	  .dec_func = osmo_pfcp_dec_32be,
	  .enc_func = osmo_pfcp_enc_32be,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_32be,
	},
	{ { OSMO_PFCP_IEI_APPLY_ACTION },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_create_far, apply_action),
	  .dec_func = osmo_pfcp_dec_apply_action,
	  .enc_func = osmo_pfcp_enc_apply_action,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_apply_action,
	},
	{ { OSMO_PFCP_IEI_FORW_PARAMS },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_create_far, forw_params),
	  .nested_ies = ies_in_forw_params,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_create_far, forw_params_present),
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_created_pdr[] = {
	{ { OSMO_PFCP_IEI_PDR_ID },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_created_pdr, pdr_id),
	  .dec_func = osmo_pfcp_dec_16be,
	  .enc_func = osmo_pfcp_enc_16be,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_16be,
	},
	{ { OSMO_PFCP_IEI_F_TEID },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_created_pdr, local_f_teid),
	  .dec_func = osmo_pfcp_dec_f_teid,
	  .enc_func = osmo_pfcp_enc_f_teid,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_f_teid,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_created_pdr, local_f_teid_present),
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_remove_pdr[] = {
	{ { OSMO_PFCP_IEI_PDR_ID },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_remove_pdr, pdr_id),
	  .dec_func = osmo_pfcp_dec_16be,
	  .enc_func = osmo_pfcp_enc_16be,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_16be,
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_remove_far[] = {
	{ { OSMO_PFCP_IEI_FAR_ID },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_remove_far, far_id),
	  .dec_func = osmo_pfcp_dec_32be,
	  .enc_func = osmo_pfcp_enc_32be,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_32be,
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_upd_pdr[] = {
	{ { OSMO_PFCP_IEI_PDR_ID },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_upd_pdr, pdr_id),
	  .dec_func = osmo_pfcp_dec_16be,
	  .enc_func = osmo_pfcp_enc_16be,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_16be,
	},
	{ { OSMO_PFCP_IEI_OUTER_HEADER_REMOVAL },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_upd_pdr, outer_header_removal),
	  .dec_func = osmo_pfcp_dec_outer_header_removal,
	  .enc_func = osmo_pfcp_enc_outer_header_removal,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_outer_header_removal,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_upd_pdr, outer_header_removal_present),
	},
	{ { OSMO_PFCP_IEI_PDI },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_upd_pdr, pdi),
	  .nested_ies = ies_in_pdi,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_upd_pdr, pdi_present),
	},
	{ { OSMO_PFCP_IEI_FAR_ID },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_upd_pdr, far_id),
	  .dec_func = osmo_pfcp_dec_32be,
	  .enc_func = osmo_pfcp_enc_32be,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_32be,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_upd_pdr, far_id_present),
	},
	{ { OSMO_PFCP_IEI_ACTIVATE_PREDEFINED_RULES },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_upd_pdr, activate_predefined_rules),
	  .dec_func = osmo_pfcp_dec_activate_predefined_rules,
	  .enc_func = osmo_pfcp_enc_activate_predefined_rules,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_activate_predefined_rules,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_upd_pdr, activate_predefined_rules_present),
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_upd_forw_params[] = {
	{ { OSMO_PFCP_IEI_DESTINATION_IFACE },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_upd_forw_params, destination_iface),
	  .dec_func = osmo_pfcp_dec_dest_iface,
	  .enc_func = osmo_pfcp_enc_dest_iface,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_dest_iface,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_upd_forw_params, destination_iface_present),
	},
	{ { OSMO_PFCP_IEI_NETWORK_INST },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_upd_forw_params, network_inst),
	  .dec_func = osmo_pfcp_dec_network_inst,
	  .enc_func = osmo_pfcp_enc_network_inst,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_network_inst,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_upd_forw_params, network_inst_present),
	},
	{ { OSMO_PFCP_IEI_OUTER_HEADER_CREATION },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_upd_forw_params, outer_header_creation),
	  .dec_func = osmo_pfcp_dec_outer_header_creation,
	  .enc_func = osmo_pfcp_enc_outer_header_creation,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_outer_header_creation,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_upd_forw_params, outer_header_creation_present),
	},
	{ { OSMO_PFCP_IEI_TRAFFIC_ENDPOINT_ID },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_upd_forw_params, linked_te_id),
	  .dec_func = osmo_pfcp_dec_8,
	  .enc_func = osmo_pfcp_enc_8,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_8,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_upd_forw_params, linked_te_id_present),
	},
	{ { OSMO_PFCP_IEI_3GPP_IFACE_TYPE },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_upd_forw_params, destination_iface_type),
	  .dec_func = osmo_pfcp_dec_3gpp_iface_type,
	  .enc_func = osmo_pfcp_enc_3gpp_iface_type,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_3gpp_iface_type,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_upd_forw_params, destination_iface_type_present),
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_upd_far[] = {
	{ { OSMO_PFCP_IEI_FAR_ID },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_upd_far, far_id),
	  .dec_func = osmo_pfcp_dec_32be,
	  .enc_func = osmo_pfcp_enc_32be,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_32be,
	},
	{ { OSMO_PFCP_IEI_APPLY_ACTION },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_upd_far, apply_action),
	  .dec_func = osmo_pfcp_dec_apply_action,
	  .enc_func = osmo_pfcp_enc_apply_action,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_apply_action,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_upd_far, apply_action_present),
	},
	{ { OSMO_PFCP_IEI_UPD_FORW_PARAMS },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_upd_far, upd_forw_params),
	  .nested_ies = ies_in_upd_forw_params,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_upd_far, upd_forw_params_present),
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_updated_pdr[] = {
	{ { OSMO_PFCP_IEI_PDR_ID },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_updated_pdr, pdr_id),
	  .dec_func = osmo_pfcp_dec_16be,
	  .enc_func = osmo_pfcp_enc_16be,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_16be,
	},
	{ { OSMO_PFCP_IEI_F_TEID },
	  .memb_ofs = offsetof(struct osmo_pfcp_ie_updated_pdr, local_f_teid),
	  .dec_func = osmo_pfcp_dec_f_teid,
	  .enc_func = osmo_pfcp_enc_f_teid,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_f_teid,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(struct osmo_pfcp_ie_updated_pdr, local_f_teid_present),
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_msg_heartbeat_req[] = {
	{ { OSMO_PFCP_IEI_RECOVERY_TIME_STAMP },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, heartbeat_req.recovery_time_stamp),
	  .dec_func = osmo_pfcp_dec_32be,
	  .enc_func = osmo_pfcp_enc_32be,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_32be,
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_msg_heartbeat_resp[] = {
	{ { OSMO_PFCP_IEI_RECOVERY_TIME_STAMP },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, heartbeat_resp.recovery_time_stamp),
	  .dec_func = osmo_pfcp_dec_32be,
	  .enc_func = osmo_pfcp_enc_32be,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_32be,
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_msg_assoc_setup_req[] = {
	{ { OSMO_PFCP_IEI_NODE_ID },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, assoc_setup_req.node_id),
	  .dec_func = osmo_pfcp_dec_node_id,
	  .enc_func = osmo_pfcp_enc_node_id,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_node_id,
	},
	{ { OSMO_PFCP_IEI_RECOVERY_TIME_STAMP },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, assoc_setup_req.recovery_time_stamp),
	  .dec_func = osmo_pfcp_dec_32be,
	  .enc_func = osmo_pfcp_enc_32be,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_32be,
	},
	{ { OSMO_PFCP_IEI_UP_FUNCTION_FEATURES },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, assoc_setup_req.up_function_features),
	  .dec_func = osmo_pfcp_dec_up_function_features,
	  .enc_func = osmo_pfcp_enc_up_function_features,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_up_function_features,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(union osmo_pfcp_ies, assoc_setup_req.up_function_features_present),
	},
	{ { OSMO_PFCP_IEI_CP_FUNCTION_FEATURES },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, assoc_setup_req.cp_function_features),
	  .dec_func = osmo_pfcp_dec_cp_function_features,
	  .enc_func = osmo_pfcp_enc_cp_function_features,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_cp_function_features,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(union osmo_pfcp_ies, assoc_setup_req.cp_function_features_present),
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_msg_assoc_setup_resp[] = {
	{ { OSMO_PFCP_IEI_NODE_ID },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, assoc_setup_resp.node_id),
	  .dec_func = osmo_pfcp_dec_node_id,
	  .enc_func = osmo_pfcp_enc_node_id,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_node_id,
	},
	{ { OSMO_PFCP_IEI_CAUSE },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, assoc_setup_resp.cause),
	  .dec_func = osmo_pfcp_dec_cause,
	  .enc_func = osmo_pfcp_enc_cause,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_cause,
	},
	{ { OSMO_PFCP_IEI_RECOVERY_TIME_STAMP },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, assoc_setup_resp.recovery_time_stamp),
	  .dec_func = osmo_pfcp_dec_32be,
	  .enc_func = osmo_pfcp_enc_32be,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_32be,
	},
	{ { OSMO_PFCP_IEI_UP_FUNCTION_FEATURES },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, assoc_setup_resp.up_function_features),
	  .dec_func = osmo_pfcp_dec_up_function_features,
	  .enc_func = osmo_pfcp_enc_up_function_features,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_up_function_features,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(union osmo_pfcp_ies, assoc_setup_resp.up_function_features_present),
	},
	{ { OSMO_PFCP_IEI_CP_FUNCTION_FEATURES },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, assoc_setup_resp.cp_function_features),
	  .dec_func = osmo_pfcp_dec_cp_function_features,
	  .enc_func = osmo_pfcp_enc_cp_function_features,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_cp_function_features,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(union osmo_pfcp_ies, assoc_setup_resp.cp_function_features_present),
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_msg_assoc_release_req[] = {
	{ { OSMO_PFCP_IEI_NODE_ID },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, assoc_release_req.node_id),
	  .dec_func = osmo_pfcp_dec_node_id,
	  .enc_func = osmo_pfcp_enc_node_id,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_node_id,
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_msg_assoc_release_resp[] = {
	{ { OSMO_PFCP_IEI_NODE_ID },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, assoc_release_resp.node_id),
	  .dec_func = osmo_pfcp_dec_node_id,
	  .enc_func = osmo_pfcp_enc_node_id,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_node_id,
	},
	{ { OSMO_PFCP_IEI_CAUSE },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, assoc_release_resp.cause),
	  .dec_func = osmo_pfcp_dec_cause,
	  .enc_func = osmo_pfcp_enc_cause,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_cause,
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_msg_session_est_req[] = {
	{ { OSMO_PFCP_IEI_NODE_ID },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_est_req.node_id),
	  .dec_func = osmo_pfcp_dec_node_id,
	  .enc_func = osmo_pfcp_enc_node_id,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_node_id,
	},
	{ { OSMO_PFCP_IEI_F_SEID },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_est_req.cp_f_seid),
	  .dec_func = osmo_pfcp_dec_f_seid,
	  .enc_func = osmo_pfcp_enc_f_seid,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_f_seid,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(union osmo_pfcp_ies, session_est_req.cp_f_seid_present),
	},
	{ { OSMO_PFCP_IEI_CREATE_PDR },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_est_req.create_pdr),
	  .nested_ies = ies_in_create_pdr,
	  .memb_array_pitch = OSMO_MEMB_ARRAY_PITCH(union osmo_pfcp_ies, session_est_req.create_pdr),
	  .has_count = true, .count_max = 32,
	  .count_mandatory = 1,
	  .count_ofs = offsetof(union osmo_pfcp_ies, session_est_req.create_pdr_count),
	},
	{ { OSMO_PFCP_IEI_CREATE_FAR },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_est_req.create_far),
	  .nested_ies = ies_in_create_far,
	  .memb_array_pitch = OSMO_MEMB_ARRAY_PITCH(union osmo_pfcp_ies, session_est_req.create_far),
	  .has_count = true, .count_max = 32,
	  .count_mandatory = 1,
	  .count_ofs = offsetof(union osmo_pfcp_ies, session_est_req.create_far_count),
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_msg_session_est_resp[] = {
	{ { OSMO_PFCP_IEI_NODE_ID },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_est_resp.node_id),
	  .dec_func = osmo_pfcp_dec_node_id,
	  .enc_func = osmo_pfcp_enc_node_id,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_node_id,
	},
	{ { OSMO_PFCP_IEI_CAUSE },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_est_resp.cause),
	  .dec_func = osmo_pfcp_dec_cause,
	  .enc_func = osmo_pfcp_enc_cause,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_cause,
	},
	{ { OSMO_PFCP_IEI_OFFENDING_IE },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_est_resp.offending_ie),
	  .dec_func = osmo_pfcp_dec_offending_ie,
	  .enc_func = osmo_pfcp_enc_offending_ie,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_offending_ie,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(union osmo_pfcp_ies, session_est_resp.offending_ie_present),
	},
	{ { OSMO_PFCP_IEI_F_SEID },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_est_resp.up_f_seid),
	  .dec_func = osmo_pfcp_dec_f_seid,
	  .enc_func = osmo_pfcp_enc_f_seid,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_f_seid,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(union osmo_pfcp_ies, session_est_resp.up_f_seid_present),
	},
	{ { OSMO_PFCP_IEI_CREATED_PDR },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_est_resp.created_pdr),
	  .nested_ies = ies_in_created_pdr,
	  .memb_array_pitch = OSMO_MEMB_ARRAY_PITCH(union osmo_pfcp_ies, session_est_resp.created_pdr),
	  .has_count = true, .count_max = 32,
	  .count_mandatory = 0,
	  .count_ofs = offsetof(union osmo_pfcp_ies, session_est_resp.created_pdr_count),
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_msg_session_mod_req[] = {
	{ { OSMO_PFCP_IEI_F_SEID },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_mod_req.cp_f_seid),
	  .dec_func = osmo_pfcp_dec_f_seid,
	  .enc_func = osmo_pfcp_enc_f_seid,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_f_seid,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(union osmo_pfcp_ies, session_mod_req.cp_f_seid_present),
	},
	{ { OSMO_PFCP_IEI_REMOVE_PDR },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_mod_req.remove_pdr),
	  .nested_ies = ies_in_remove_pdr,
	  .memb_array_pitch = OSMO_MEMB_ARRAY_PITCH(union osmo_pfcp_ies, session_mod_req.remove_pdr),
	  .has_count = true, .count_max = 32,
	  .count_mandatory = 0,
	  .count_ofs = offsetof(union osmo_pfcp_ies, session_mod_req.remove_pdr_count),
	},
	{ { OSMO_PFCP_IEI_REMOVE_FAR },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_mod_req.remove_far),
	  .nested_ies = ies_in_remove_far,
	  .memb_array_pitch = OSMO_MEMB_ARRAY_PITCH(union osmo_pfcp_ies, session_mod_req.remove_far),
	  .has_count = true, .count_max = 32,
	  .count_mandatory = 0,
	  .count_ofs = offsetof(union osmo_pfcp_ies, session_mod_req.remove_far_count),
	},
	{ { OSMO_PFCP_IEI_CREATE_PDR },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_mod_req.create_pdr),
	  .nested_ies = ies_in_create_pdr,
	  .memb_array_pitch = OSMO_MEMB_ARRAY_PITCH(union osmo_pfcp_ies, session_mod_req.create_pdr),
	  .has_count = true, .count_max = 32,
	  .count_mandatory = 0,
	  .count_ofs = offsetof(union osmo_pfcp_ies, session_mod_req.create_pdr_count),
	},
	{ { OSMO_PFCP_IEI_CREATE_FAR },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_mod_req.create_far),
	  .nested_ies = ies_in_create_far,
	  .memb_array_pitch = OSMO_MEMB_ARRAY_PITCH(union osmo_pfcp_ies, session_mod_req.create_far),
	  .has_count = true, .count_max = 32,
	  .count_mandatory = 0,
	  .count_ofs = offsetof(union osmo_pfcp_ies, session_mod_req.create_far_count),
	},
	{ { OSMO_PFCP_IEI_UPD_PDR },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_mod_req.upd_pdr),
	  .nested_ies = ies_in_upd_pdr,
	  .memb_array_pitch = OSMO_MEMB_ARRAY_PITCH(union osmo_pfcp_ies, session_mod_req.upd_pdr),
	  .has_count = true, .count_max = 32,
	  .count_mandatory = 0,
	  .count_ofs = offsetof(union osmo_pfcp_ies, session_mod_req.upd_pdr_count),
	},
	{ { OSMO_PFCP_IEI_UPD_FAR },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_mod_req.upd_far),
	  .nested_ies = ies_in_upd_far,
	  .memb_array_pitch = OSMO_MEMB_ARRAY_PITCH(union osmo_pfcp_ies, session_mod_req.upd_far),
	  .has_count = true, .count_max = 32,
	  .count_mandatory = 0,
	  .count_ofs = offsetof(union osmo_pfcp_ies, session_mod_req.upd_far_count),
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_msg_session_mod_resp[] = {
	{ { OSMO_PFCP_IEI_CAUSE },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_mod_resp.cause),
	  .dec_func = osmo_pfcp_dec_cause,
	  .enc_func = osmo_pfcp_enc_cause,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_cause,
	},
	{ { OSMO_PFCP_IEI_OFFENDING_IE },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_mod_resp.offending_ie),
	  .dec_func = osmo_pfcp_dec_offending_ie,
	  .enc_func = osmo_pfcp_enc_offending_ie,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_offending_ie,
	  .has_presence_flag = true,
	  .presence_flag_ofs = offsetof(union osmo_pfcp_ies, session_mod_resp.offending_ie_present),
	},
	{ { OSMO_PFCP_IEI_CREATED_PDR },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_mod_resp.created_pdr),
	  .nested_ies = ies_in_created_pdr,
	  .memb_array_pitch = OSMO_MEMB_ARRAY_PITCH(union osmo_pfcp_ies, session_mod_resp.created_pdr),
	  .has_count = true, .count_max = 32,
	  .count_mandatory = 0,
	  .count_ofs = offsetof(union osmo_pfcp_ies, session_mod_resp.created_pdr_count),
	},
	{ { OSMO_PFCP_IEI_UPDATED_PDR },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_mod_resp.updated_pdr),
	  .nested_ies = ies_in_updated_pdr,
	  .memb_array_pitch = OSMO_MEMB_ARRAY_PITCH(union osmo_pfcp_ies, session_mod_resp.updated_pdr),
	  .has_count = true, .count_max = 32,
	  .count_mandatory = 0,
	  .count_ofs = offsetof(union osmo_pfcp_ies, session_mod_resp.updated_pdr_count),
	},
	{}
};

static const struct osmo_gtlv_coding ies_in_msg_session_del_req[] = {
	{}
};

static const struct osmo_gtlv_coding ies_in_msg_session_del_resp[] = {
	{ { OSMO_PFCP_IEI_CAUSE },
	  .memb_ofs = offsetof(union osmo_pfcp_ies, session_del_resp.cause),
	  .dec_func = osmo_pfcp_dec_cause,
	  .enc_func = osmo_pfcp_enc_cause,
	  .enc_to_str_func = osmo_pfcp_enc_to_str_cause,
	},
	{}
};

static const struct osmo_gtlv_coding *msg_defs[] = {
	[OSMO_PFCP_MSGT_HEARTBEAT_REQ] = ies_in_msg_heartbeat_req,
	[OSMO_PFCP_MSGT_HEARTBEAT_RESP] = ies_in_msg_heartbeat_resp,
	[OSMO_PFCP_MSGT_ASSOC_SETUP_REQ] = ies_in_msg_assoc_setup_req,
	[OSMO_PFCP_MSGT_ASSOC_SETUP_RESP] = ies_in_msg_assoc_setup_resp,
	[OSMO_PFCP_MSGT_ASSOC_RELEASE_REQ] = ies_in_msg_assoc_release_req,
	[OSMO_PFCP_MSGT_ASSOC_RELEASE_RESP] = ies_in_msg_assoc_release_resp,
	[OSMO_PFCP_MSGT_SESSION_EST_REQ] = ies_in_msg_session_est_req,
	[OSMO_PFCP_MSGT_SESSION_EST_RESP] = ies_in_msg_session_est_resp,
	[OSMO_PFCP_MSGT_SESSION_MOD_REQ] = ies_in_msg_session_mod_req,
	[OSMO_PFCP_MSGT_SESSION_MOD_RESP] = ies_in_msg_session_mod_resp,
	[OSMO_PFCP_MSGT_SESSION_DEL_REQ] = ies_in_msg_session_del_req,
	[OSMO_PFCP_MSGT_SESSION_DEL_RESP] = ies_in_msg_session_del_resp,
};

const struct osmo_gtlv_coding *osmo_pfcp_get_msg_coding(enum osmo_pfcp_message_type message_type)
{
	if (message_type >= ARRAY_SIZE(msg_defs))
		return NULL;
	return msg_defs[message_type];
}

int osmo_pfcp_ies_decode(union osmo_pfcp_ies *dst, struct osmo_gtlv_load *gtlv, bool tlv_ordered,
	enum osmo_pfcp_message_type message_type,
	osmo_gtlv_err_cb err_cb, void *err_cb_data, const struct value_string *iei_strs)
{
	return osmo_gtlvs_decode(dst, sizeof(*dst), 0, gtlv, tlv_ordered, osmo_pfcp_get_msg_coding(message_type),
		err_cb, err_cb_data, iei_strs);
}

int osmo_pfcp_ies_encode(struct osmo_gtlv_put *gtlv, const union osmo_pfcp_ies *src,
	enum osmo_pfcp_message_type message_type, osmo_gtlv_err_cb err_cb, void *err_cb_data, const struct value_string *iei_strs)
{
	return osmo_gtlvs_encode(gtlv, src, sizeof(*src), 0, osmo_pfcp_get_msg_coding(message_type),
		err_cb, err_cb_data, iei_strs);
}

int osmo_pfcp_ies_encode_to_str(char *buf, size_t buflen, const union osmo_pfcp_ies *src,
	enum osmo_pfcp_message_type message_type, const struct value_string *iei_strs)
{
	return osmo_gtlvs_encode_to_str_buf(buf, buflen, src, sizeof(*src), 0, osmo_pfcp_get_msg_coding(message_type), iei_strs);
}
