diff --git a/src/common/3gpp_29.244.h b/src/common/3gpp_29.244.h index bbacf40..bd23959 100644 --- a/src/common/3gpp_29.244.h +++ b/src/common/3gpp_29.244.h @@ -40,6 +40,11 @@ namespace pfcp { +typedef struct enterprise_specific_s { + uint16_t enterprise_id; + std::string proprietary_data; +} enterprise_specific_t; + struct pfcp_exception : public std::exception { pfcp_exception() throw() { cause = 0; @@ -334,6 +339,7 @@ struct pfcp_ie_value_exception : public pfcp_ie_exception { #define PFCP_SESSION_DELETION_RESPONSE (55) #define PFCP_SESSION_REPORT_REQUEST (56) #define PFCP_SESSION_REPORT_RESPONSE (57) +#define PFCP_IE_ENTERPRISE_SPECIFIC (32770) } // namespace pfcp namespace pfcp { diff --git a/src/oai_spgwc/PfcpUpNodes.cpp b/src/oai_spgwc/PfcpUpNodes.cpp index d7f153a..41bfc08 100644 --- a/src/oai_spgwc/PfcpUpNodes.cpp +++ b/src/oai_spgwc/PfcpUpNodes.cpp @@ -200,7 +200,8 @@ void pgwc::PfcpUpNodes::AssociationSetupRequest( pfcp::node_id_t& node_id, pfcp::recovery_time_stamp_t& recovery_time_stamp, std::pair& up_function_features, std::pair& - user_plane_ip_resource_information) { + user_plane_ip_resource_information, + std::pair& enterprise_specific) { Logger::pgwc_app().info( "RX AssociationSetupRequest FQDN %s", node_id.fqdn.c_str()); std::unique_lock l(m_pending_nodes); diff --git a/src/oai_spgwc/PfcpUpNodes.hpp b/src/oai_spgwc/PfcpUpNodes.hpp index 45b80f7..a2aa16b 100644 --- a/src/oai_spgwc/PfcpUpNodes.hpp +++ b/src/oai_spgwc/PfcpUpNodes.hpp @@ -143,7 +143,8 @@ class PfcpUpNodes { pfcp::recovery_time_stamp_t& recovery_time_stamp, std::pair& up_function_features, std::pair& - user_plane_ip_resource_information); + user_plane_ip_resource_information, + std::pair& enterprise_specific); bool AddUpNode(const std::string t_up_ip, const std::string t_apn); bool GetUpNode( diff --git a/src/oai_spgwc/pgwc_sxab.cpp b/src/oai_spgwc/pgwc_sxab.cpp index e5cebf9..35aea38 100644 --- a/src/oai_spgwc/pgwc_sxab.cpp +++ b/src/oai_spgwc/pgwc_sxab.cpp @@ -347,11 +347,15 @@ void pgwc_sxab::handle_receive_association_setup_request( "IE!, ignore message"); return; } + if (msg_ies_container.enterprise_specific.first) { + // Do nothing for now + } PfcpUpNodes::Instance().AssociationSetupRequest( trxn_id, remote_endpoint, msg_ies_container.node_id.second, msg_ies_container.recovery_time_stamp.second, msg_ies_container.up_function_features, - msg_ies_container.user_plane_ip_resource_information); + msg_ies_container.user_plane_ip_resource_information, + msg_ies_container.enterprise_specific); } } @@ -468,15 +472,15 @@ void pgwc_sxab::handle_receive_session_report_request( //------------------------------------------------------------------------------ void pgwc_sxab::send_sx_msg(itti_sxab_association_setup_request& i) { - pfcp::recovery_time_stamp_t r = {.recovery_time_stamp = - (uint32_t) recovery_time_stamp}; + pfcp::recovery_time_stamp_t r = { + .recovery_time_stamp = (uint32_t) recovery_time_stamp}; i.pfcp_ies.set(r); send_request(i.r_endpoint, i.pfcp_ies, TASK_PGWC_SX, i.trxn_id); } //------------------------------------------------------------------------------ void pgwc_sxab::send_sx_msg(itti_sxab_association_setup_response& i) { - pfcp::recovery_time_stamp_t r = {.recovery_time_stamp = - (uint32_t) recovery_time_stamp}; + pfcp::recovery_time_stamp_t r = { + .recovery_time_stamp = (uint32_t) recovery_time_stamp}; i.pfcp_ies.set(r); if (cp_function_features.has_features()) { i.pfcp_ies.set(cp_function_features); @@ -490,8 +494,8 @@ void pgwc_sxab::send_sx_msg(itti_sxab_session_report_response& i) { //------------------------------------------------------------------------------ void pgwc_sxab::send_heartbeat_request(std::shared_ptr& a) { pfcp::pfcp_heartbeat_request h = {}; - pfcp::recovery_time_stamp_t r = {.recovery_time_stamp = - (uint32_t) recovery_time_stamp}; + pfcp::recovery_time_stamp_t r = { + .recovery_time_stamp = (uint32_t) recovery_time_stamp}; h.set(r); a->timer_heartbeat = itti_inst->timer_setup( @@ -507,8 +511,8 @@ void pgwc_sxab::send_heartbeat_request(std::shared_ptr& a) { void pgwc_sxab::send_heartbeat_response( const endpoint& r_endpoint, const uint64_t trxn_id) { pfcp::pfcp_heartbeat_response h = {}; - pfcp::recovery_time_stamp_t r = {.recovery_time_stamp = - (uint32_t) recovery_time_stamp}; + pfcp::recovery_time_stamp_t r = { + .recovery_time_stamp = (uint32_t) recovery_time_stamp}; h.set(r); send_response(r_endpoint, h, trxn_id); } diff --git a/src/pfcp/3gpp_29.244.cpp b/src/pfcp/3gpp_29.244.cpp index 94f5ab6..e71254f 100644 --- a/src/pfcp/3gpp_29.244.cpp +++ b/src/pfcp/3gpp_29.244.cpp @@ -38,6 +38,11 @@ pfcp_ie* pfcp_ie::new_pfcp_ie_from_stream(std::istream& is) { tlv.load_from(is); if (tlv.length) { switch (tlv.type) { + case PFCP_IE_ENTERPRISE_SPECIFIC: { + pfcp_enterprise_specific_ie* ie = new pfcp_enterprise_specific_ie(tlv); + ie->load_from(is); + return ie; + } break; case PFCP_IE_CREATE_PDR: { pfcp_create_pdr_ie* ie = new pfcp_create_pdr_ie(tlv); ie->load_from(is); diff --git a/src/pfcp/3gpp_29.244.hpp b/src/pfcp/3gpp_29.244.hpp index 3a3fd29..a49e82e 100644 --- a/src/pfcp/3gpp_29.244.hpp +++ b/src/pfcp/3gpp_29.244.hpp @@ -107,7 +107,7 @@ class pfcp_ie : public stream_serializable { pfcp_ie() : tlv() {} explicit pfcp_ie(const pfcp_tlv& t) : tlv(t) {} - explicit pfcp_ie(const uint8_t tlv_type) : tlv() { tlv.type = tlv_type; } + explicit pfcp_ie(const uint16_t tlv_type) : tlv() { tlv.type = tlv_type; } virtual ~pfcp_ie(){}; @@ -602,6 +602,71 @@ class pfcp_cause_ie : public pfcp_ie { } }; //------------------------------------- +// IE ENTERPRISE SPECIFIC +class pfcp_enterprise_specific_ie : public pfcp_ie { + public: + uint16_t enterprise_id; + std::string proprietary_data; + + //-------- + explicit pfcp_enterprise_specific_ie(const pfcp::enterprise_specific_t& b) + : pfcp_ie(PFCP_IE_ENTERPRISE_SPECIFIC) { + enterprise_id = b.enterprise_id; + proprietary_data = b.proprietary_data; + tlv.set_length(2 + proprietary_data.size()); + } + //-------- + pfcp_enterprise_specific_ie() : pfcp_ie(PFCP_IE_ENTERPRISE_SPECIFIC) { + enterprise_id = 0; + proprietary_data = {}; + tlv.set_length(2); + } + // -------- + explicit pfcp_enterprise_specific_ie(const pfcp_tlv& t) + : pfcp_ie(t), enterprise_id(0), proprietary_data(){}; + + //-------- + void to_core_type(pfcp::enterprise_specific_t& b) { + b.enterprise_id = enterprise_id; + b.proprietary_data = proprietary_data; + } + //-------- + void dump_to(std::ostream& os) { + tlv.dump_to(os); + os.write( + reinterpret_cast(&enterprise_id), sizeof(enterprise_id)); + os << enterprise_id; + os.write( + reinterpret_cast(&proprietary_data), + sizeof(proprietary_data)); + os << proprietary_data; + } + //-------- + void load_from(std::istream& is) { + // tlv.load_from(is); + if (tlv.get_length() < 2) { + throw pfcp_tlv_bad_length_exception( + tlv.type, tlv.get_length(), __FILE__, __LINE__); + } + is.read(reinterpret_cast(&enterprise_id), sizeof(enterprise_id)); + + char e[tlv.get_length() - 2]; + is.read(e, tlv.get_length() - 2); + proprietary_data.assign(e, tlv.get_length() - 2); + + if (tlv.get_length() != (2 + proprietary_data.size())) { + throw pfcp_tlv_bad_length_exception( + tlv.type, tlv.get_length(), __FILE__, __LINE__); + } + } + //-------- + void to_core_type(pfcp_ies_container& s) { + pfcp::enterprise_specific_t enterprise_specific = {}; + to_core_type(enterprise_specific); + s.set(enterprise_specific); + } +}; +//------------------------------------- // IE SOURCE_INTERFACE class pfcp_source_interface_ie : public pfcp_ie { public: diff --git a/src/pfcp/msg_pfcp.hpp b/src/pfcp/msg_pfcp.hpp index a073455..2db44c1 100644 --- a/src/pfcp/msg_pfcp.hpp +++ b/src/pfcp/msg_pfcp.hpp @@ -90,6 +90,16 @@ class pfcp_ies_container { public: static const uint8_t msg_id = 0; + // PFCP_IE_ENTERPRISE_SPECIFIC + virtual bool get(pfcp::enterprise_specific_t& v) const { + throw pfcp_msg_illegal_ie_exception( + 0, PFCP_IE_ENTERPRISE_SPECIFIC, __FILE__, __LINE__); + } + virtual void set(const pfcp::enterprise_specific_t& v) { + throw pfcp_msg_illegal_ie_exception( + 0, PFCP_IE_ENTERPRISE_SPECIFIC, __FILE__, __LINE__); + } + // PFCP_IE_CREATE_PDR virtual bool get(pfcp::create_pdr& v) const { throw pfcp_msg_illegal_ie_exception( @@ -5568,13 +5578,15 @@ class pfcp_association_setup_request : public pfcp_ies_container { std::pair cp_function_features; std::pair user_plane_ip_resource_information; + std::pair enterprise_specific; pfcp_association_setup_request() : node_id(), recovery_time_stamp(), up_function_features(), cp_function_features(), - user_plane_ip_resource_information() {} + user_plane_ip_resource_information(), + enterprise_specific() {} pfcp_association_setup_request(const pfcp_association_setup_request& i) { node_id = i.node_id; @@ -5582,6 +5594,7 @@ class pfcp_association_setup_request : public pfcp_ies_container { up_function_features = i.up_function_features; cp_function_features = i.cp_function_features; user_plane_ip_resource_information = i.user_plane_ip_resource_information; + enterprise_specific = i.enterprise_specific; } const char* get_msg_name() const { return "PFCP_ASSOCIATION_SETUP_REQUEST"; }; @@ -5620,6 +5633,13 @@ class pfcp_association_setup_request : public pfcp_ies_container { } return false; } + bool get(pfcp::enterprise_specific_t& v) const { + if (enterprise_specific.first) { + v = enterprise_specific.second; + return true; + } + return false; + } void set(const pfcp::node_id_t& v) { node_id.first = true; @@ -5641,6 +5661,10 @@ class pfcp_association_setup_request : public pfcp_ies_container { user_plane_ip_resource_information.first = true; user_plane_ip_resource_information.second = v; } + void set(const pfcp::enterprise_specific_t& v) { + enterprise_specific.first = true; + enterprise_specific.second = v; + } }; //------------------------------------------------------------------------------ @@ -5655,6 +5679,7 @@ class pfcp_association_setup_response : public pfcp_ies_container { std::pair cp_function_features; std::pair user_plane_ip_resource_information; + std::pair enterprise_specific; pfcp_association_setup_response() : node_id(), @@ -5662,7 +5687,8 @@ class pfcp_association_setup_response : public pfcp_ies_container { recovery_time_stamp(), up_function_features(), cp_function_features(), - user_plane_ip_resource_information() {} + user_plane_ip_resource_information(), + enterprise_specific() {} pfcp_association_setup_response(const pfcp_association_setup_response& i) { node_id = i.node_id; @@ -5671,6 +5697,7 @@ class pfcp_association_setup_response : public pfcp_ies_container { up_function_features = i.up_function_features; cp_function_features = i.cp_function_features; user_plane_ip_resource_information = i.user_plane_ip_resource_information; + enterprise_specific = i.enterprise_specific; } const char* get_msg_name() const { return "PFCP_ASSOCIATION_SETUP_RESPONSE"; @@ -5718,6 +5745,13 @@ class pfcp_association_setup_response : public pfcp_ies_container { } return false; } + bool get(pfcp::enterprise_specific_t& v) const { + if (enterprise_specific.first) { + v = enterprise_specific.second; + return true; + } + return false; + } void set(const pfcp::node_id_t& v) { node_id.first = true; @@ -5743,6 +5777,10 @@ class pfcp_association_setup_response : public pfcp_ies_container { user_plane_ip_resource_information.first = true; user_plane_ip_resource_information.second = v; } + void set(const pfcp::enterprise_specific_t& v) { + enterprise_specific.first = true; + enterprise_specific.second = v; + } }; //------------------------------------------------------------------------------