From 7e1fe4cc4ff37fb542dd45af2c717cea743ecace Mon Sep 17 00:00:00 2001 From: Thangaraj Palanisamy Date: Thu, 27 Feb 2025 19:48:00 +0530 Subject: [PATCH] enable E2E support on VSOMEIP-STACK - e2e enable - e2e receiver side impl - To handle the error case when crc check or counter fails - E2E sender side implementation - Remove instance ID from data_id in vsomeip E2E protect - Remove instance ID from data_id in vsomeip E2E check According to the AUTOSAR E2E protocol specification, there is no requirement to include an instance ID along with the Data ID. Signed-off-by: Thangaraj Palanisamy --- Android.bp | 3 +- CMakeLists.txt | 3 + .../include/e2e/profile/e2e_provider.hpp | 2 + .../include/e2e/profile/e2e_provider_impl.hpp | 8 +- .../e2e/profile/profile04/header_info.hpp | 42 +++++ .../e2e/profile/profile04/profile_04.hpp | 1 + .../profile/profile_interface/header_info.hpp | 34 +++++ .../src/e2e/profile/e2e_provider_impl.cpp | 38 ++++- .../src/e2e/profile/profile04/checker.cpp | 2 +- .../src/e2e/profile/profile04/header_info.cpp | 34 +++++ .../src/e2e/profile/profile04/protector.cpp | 2 +- .../routing/include/routing_manager_impl.hpp | 17 +++ .../routing/src/routing_manager_impl.cpp | 144 ++++++++++++++---- 13 files changed, 288 insertions(+), 42 deletions(-) create mode 100644 implementation/e2e_protection/include/e2e/profile/profile04/header_info.hpp create mode 100644 implementation/e2e_protection/include/e2e/profile/profile_interface/header_info.hpp create mode 100644 implementation/e2e_protection/src/e2e/profile/profile04/header_info.cpp diff --git a/Android.bp b/Android.bp index d60fa0f73..ceb61fa6a 100644 --- a/Android.bp +++ b/Android.bp @@ -21,7 +21,7 @@ libvsomeip_cfg_srcs = [ ] libvsomeip_e2e_srcs = [ - "implementation/e2e_protection/src/*.cpp", + "implementation/e2e_protection/src/**/*.cpp", ] libvsomeip_sd_srcs = [ @@ -83,6 +83,7 @@ cc_library_shared { "-DVSOMEIP_COMPAT_VERSION=\"3.5.4\"", "-DVSOMEIP_BASE_PATH=\"/vendor/run/someip/\"", "-DUSE_DLT", + "-DENABLE_E2E_FEATURE" ], ldflags: [ diff --git a/CMakeLists.txt b/CMakeLists.txt index c659bbb74..2978c2bda 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,6 +109,9 @@ if (ENABLE_SIGNAL_HANDLING) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVSOMEIP_ENABLE_SIGNAL_HANDLING") endif () +# Enable E2E feature +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DENABLE_E2E_FEATURE") + # Event caching if (ENABLE_DEFAULT_EVENT_CACHING) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVSOMEIP_ENABLE_DEFAULT_EVENT_CACHING") diff --git a/implementation/e2e_protection/include/e2e/profile/e2e_provider.hpp b/implementation/e2e_protection/include/e2e/profile/e2e_provider.hpp index 51e42e17f..3851b6ac0 100644 --- a/implementation/e2e_protection/include/e2e/profile/e2e_provider.hpp +++ b/implementation/e2e_protection/include/e2e/profile/e2e_provider.hpp @@ -31,6 +31,8 @@ class e2e_provider { virtual void check(e2exf::data_identifier_t id, const e2e_buffer &_buffer, instance_t _instance, e2e::profile_interface::check_status_t &_generic_check_status) = 0; + virtual bool should_remove_e2e_header(e2exf::data_identifier_t id) = 0; + virtual bool get_header_offset_and_length(e2exf::data_identifier_t id,length_t& offset, length_t& length) = 0; }; } // namespace e2e diff --git a/implementation/e2e_protection/include/e2e/profile/e2e_provider_impl.hpp b/implementation/e2e_protection/include/e2e/profile/e2e_provider_impl.hpp index 631f87f29..c7bf78984 100644 --- a/implementation/e2e_protection/include/e2e/profile/e2e_provider_impl.hpp +++ b/implementation/e2e_protection/include/e2e/profile/e2e_provider_impl.hpp @@ -11,6 +11,7 @@ #include "e2e_provider.hpp" #include "profile_interface/checker.hpp" +#include "profile_interface/header_info.hpp" #include "profile_interface/protector.hpp" #include "../../../../../interface/vsomeip/export.hpp" @@ -39,19 +40,22 @@ class e2e_provider_impl : VSOMEIP_EXPORT void check(e2exf::data_identifier_t id, const e2e_buffer &_buffer, instance_t _instance, profile_interface::check_status_t &_generic_check_status) override; + VSOMEIP_EXPORT bool should_remove_e2e_header(e2exf::data_identifier_t id) override; + VSOMEIP_EXPORT bool get_header_offset_and_length(e2exf::data_identifier_t id,length_t& offset, length_t& length) override; private: std::map> custom_protectors_; std::map> custom_checkers_; + std::map> header_infos_; std::map custom_bases_; template - config_t make_e2e_profile_config(const std::shared_ptr& config); + config_t make_e2e_profile_config(const e2exf::data_identifier_t data_identifier, const std::shared_ptr& config); template void process_e2e_profile(std::shared_ptr config) { const e2exf::data_identifier_t data_identifier = {config->service_id, config->event_id}; - config_t profile_config = make_e2e_profile_config(config); + config_t profile_config = make_e2e_profile_config(data_identifier,config); std::shared_ptr checker; if ((config->variant == "checker") || (config->variant == "both")) { diff --git a/implementation/e2e_protection/include/e2e/profile/profile04/header_info.hpp b/implementation/e2e_protection/include/e2e/profile/profile04/header_info.hpp new file mode 100644 index 000000000..434216365 --- /dev/null +++ b/implementation/e2e_protection/include/e2e/profile/profile04/header_info.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2025-2026 Valeo +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +/* +** file header_info.hpp +** brief Implementation of header info interface to save header info for profile 04 +*/ + +#ifndef VSOMEIP_V3_E2E_PROFILE04_HEADER_INFO_HPP +#define VSOMEIP_V3_E2E_PROFILE04_HEADER_INFO_HPP + +#include + +#include "../profile04/profile_04.hpp" +#include "../profile_interface/header_info.hpp" + +namespace vsomeip_v3 { +namespace e2e { +namespace profile04 { + +class profile_04_header_info final : public e2e::profile_interface::profile_header_info { + +public: + profile_04_header_info(void) = delete; + + explicit profile_04_header_info(length_t _offet_); + length_t get_e2e_header_offset() override; + length_t get_e2e_header_length() override; + bool should_remove_header() override; + +private: + length_t header_len_; + length_t crc_offset_; +}; + +} // namespace profile_04 +} // namespace e2e +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_E2E_PROFILE04_HEADER_INFO_HPP diff --git a/implementation/e2e_protection/include/e2e/profile/profile04/profile_04.hpp b/implementation/e2e_protection/include/e2e/profile/profile04/profile_04.hpp index 11a7ee7e1..8dc1d8569 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile04/profile_04.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile04/profile_04.hpp @@ -39,6 +39,7 @@ struct profile_config { max_delta_counter_(_max_delta_counter), base_(VSOMEIP_SOMEIP_HEADER_SIZE) { } + profile_config(const profile_config &_config) = default; profile_config &operator=(const profile_config &_config) = default; diff --git a/implementation/e2e_protection/include/e2e/profile/profile_interface/header_info.hpp b/implementation/e2e_protection/include/e2e/profile/profile_interface/header_info.hpp new file mode 100644 index 000000000..8791a59cd --- /dev/null +++ b/implementation/e2e_protection/include/e2e/profile/profile_interface/header_info.hpp @@ -0,0 +1,34 @@ +// Copyright (C) 2025-2026 Valeo +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +/* +** file header_info.hpp +** brief Interface to retrive header info +*/ + +#ifndef VSOMEIP_V3_E2E_PROFILE_INTERFACE_HEADER_INFO_HPP +#define VSOMEIP_V3_E2E_PROFILE_INTERFACE_HEADER_INFO_HPP + +#include +#include + +namespace vsomeip_v3 { +namespace e2e { +namespace profile_interface { + + +class profile_header_info { +public: + virtual ~profile_header_info() {} + virtual length_t get_e2e_header_offset() = 0; + virtual length_t get_e2e_header_length() = 0; + virtual bool should_remove_header() = 0; +}; + +} // namespace profile_interface +} // namespace e2e +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_E2E_PROFILE_INTERFACE_HEADER_INFO_HPP diff --git a/implementation/e2e_protection/src/e2e/profile/e2e_provider_impl.cpp b/implementation/e2e_protection/src/e2e/profile/e2e_provider_impl.cpp index 3a9643ee9..c3a8e7645 100644 --- a/implementation/e2e_protection/src/e2e/profile/e2e_provider_impl.cpp +++ b/implementation/e2e_protection/src/e2e/profile/e2e_provider_impl.cpp @@ -4,6 +4,7 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include +#include #include #include @@ -17,6 +18,7 @@ #include "../../../../e2e_protection/include/e2e/profile/profile04/checker.hpp" #include "../../../../e2e_protection/include/e2e/profile/profile04/profile_04.hpp" #include "../../../../e2e_protection/include/e2e/profile/profile04/protector.hpp" +#include "../../../../e2e_protection/include/e2e/profile/profile04/header_info.hpp" #include "../../../../e2e_protection/include/e2e/profile/profile05/checker.hpp" #include "../../../../e2e_protection/include/e2e/profile/profile05/profile_05.hpp" @@ -141,9 +143,30 @@ void e2e_provider_impl::check(e2exf::data_identifier_t id, } } +bool e2e_provider_impl::should_remove_e2e_header(e2exf::data_identifier_t id) +{ + auto header_info = header_infos_.find(id); + if (header_info != header_infos_.end()) + { + return header_info->second->should_remove_header(); + } + return false; +} + +bool e2e_provider_impl::get_header_offset_and_length(e2exf::data_identifier_t id,length_t& offset, length_t& length) +{ + auto header_info = header_infos_.find(id); + if(header_info != header_infos_.end()) { + length= header_info->second->get_e2e_header_length(); + offset= header_info->second->get_e2e_header_offset(); + return true; + } + return false; +} + template<> vsomeip_v3::e2e::profile01::profile_config -e2e_provider_impl::make_e2e_profile_config(const std::shared_ptr &_config) { +e2e_provider_impl::make_e2e_profile_config(const e2exf::data_identifier_t, const std::shared_ptr &_config) { uint16_t data_id = read_value_from_config(_config, "data_id"); uint16_t crc_offset = read_value_from_config(_config, "crc_offset"); uint16_t data_length = read_value_from_config(_config, "data_length"); @@ -164,7 +187,7 @@ e2e_provider_impl::make_e2e_profile_config(const std::shared_ptr &_con template<> vsomeip_v3::e2e::profile04::profile_config -e2e_provider_impl::make_e2e_profile_config(const std::shared_ptr &_config) { +e2e_provider_impl::make_e2e_profile_config(const e2exf::data_identifier_t data_identifier, const std::shared_ptr &_config) { uint32_t data_id = read_value_from_config(_config, "data_id"); @@ -183,13 +206,16 @@ e2e_provider_impl::make_e2e_profile_config(const std::shared_ptr &_con uint16_t max_delta_counter = read_value_from_config(_config, "max_delta_counter", uint16_t(0xffff)); - return e2e::profile04::profile_config(data_id, offset, + e2e::profile04::profile_config profile04_config = e2e::profile04::profile_config(data_id, offset, min_data_length, max_data_length, max_delta_counter); + header_infos_[data_identifier] = std::make_shared(static_cast(offset)); + + return profile04_config; } template<> vsomeip_v3::e2e::profile05::profile_config -e2e_provider_impl::make_e2e_profile_config(const std::shared_ptr &_config) { +e2e_provider_impl::make_e2e_profile_config(const e2exf::data_identifier_t, const std::shared_ptr &_config) { uint32_t data_id = read_value_from_config(_config, "data_id"); uint16_t data_length = read_value_from_config(_config, "data_length"); @@ -209,14 +235,14 @@ e2e_provider_impl::make_e2e_profile_config(const std::shared_ptr &_con template<> e2e::profile_custom::profile_config -e2e_provider_impl::make_e2e_profile_config(const std::shared_ptr& config) { +e2e_provider_impl::make_e2e_profile_config(const e2exf::data_identifier_t, const std::shared_ptr& config) { uint16_t crc_offset = read_value_from_config(config, "crc_offset"); return e2e::profile_custom::profile_config(crc_offset); } template<> vsomeip_v3::e2e::profile07::profile_config -e2e_provider_impl::make_e2e_profile_config(const std::shared_ptr &_config) { +e2e_provider_impl::make_e2e_profile_config(const e2exf::data_identifier_t, const std::shared_ptr &_config) { uint32_t data_id = read_value_from_config(_config, "data_id"); diff --git a/implementation/e2e_protection/src/e2e/profile/profile04/checker.cpp b/implementation/e2e_protection/src/e2e/profile/profile04/checker.cpp index 3e655f1d5..ccf962902 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile04/checker.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile04/checker.cpp @@ -47,7 +47,7 @@ void profile_04_checker::check(const e2e_buffer &_buffer, instance_t _instance, VSOMEIP_ERROR << std::hex << "E2E P04 protection: CRC32 does not match: calculated CRC: " << its_crc << " received CRC: " << its_received_crc; } else { - uint32_t its_data_id(uint32_t(_instance) << 24 | config_.data_id_); + uint32_t its_data_id(config_.data_id_); if (its_received_data_id == its_data_id && static_cast(its_received_length) == _buffer.size() && verify_counter(_instance, its_received_counter)) { diff --git a/implementation/e2e_protection/src/e2e/profile/profile04/header_info.cpp b/implementation/e2e_protection/src/e2e/profile/profile04/header_info.cpp new file mode 100644 index 000000000..129449834 --- /dev/null +++ b/implementation/e2e_protection/src/e2e/profile/profile04/header_info.cpp @@ -0,0 +1,34 @@ +// Copyright (C) 2025-2026 Valeo +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +/* +** file header_info.cpp +** brief Implementation of header info interface to save header info for profile 04 +*/ + +#include + +#include "../../../../include/e2e/profile/profile04/header_info.hpp" + +namespace vsomeip_v3 { +namespace e2e { +namespace profile04 { + +constexpr int HEADER_LENGTH=12; + +profile_04_header_info::profile_04_header_info(length_t _offet) + : header_len_(HEADER_LENGTH), crc_offset_(_offet) {} + +length_t profile_04_header_info::get_e2e_header_offset() { return crc_offset_; } + +length_t profile_04_header_info::get_e2e_header_length() { return header_len_; } + +bool profile_04_header_info::should_remove_header() { + return true; +} + +} // namespace profile04 +} // namespace e2e +} // namespace vsomeip_v3 diff --git a/implementation/e2e_protection/src/e2e/profile/profile04/protector.cpp b/implementation/e2e_protection/src/e2e/profile/profile04/protector.cpp index e6abf84b9..f87faa596 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile04/protector.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile04/protector.cpp @@ -33,7 +33,7 @@ protector::protect(e2e_buffer &_buffer, instance_t _instance) { bithelper::write_uint16_be(get_counter(_instance), &_buffer[config_.offset_ + 2]); /** @req [SWS_E2E_00366] */ - uint32_t its_data_id(uint32_t(_instance) << 24 | config_.data_id_); + uint32_t its_data_id(config_.data_id_); bithelper::write_uint32_be(its_data_id, &_buffer[config_.offset_ + 4]); /** @req [SWS_E2E_00367] */ diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp index 598b2e21f..d335362ef 100644 --- a/implementation/routing/include/routing_manager_impl.hpp +++ b/implementation/routing/include/routing_manager_impl.hpp @@ -470,6 +470,23 @@ class routing_manager_impl: public routing_manager_base, service_t _service, instance_t _instance, const boost::asio::ip::address &_remote_address) const; + bool apply_e2e_protection(const byte_t **_data, length_t &_size, + service_t _service, method_t _method, + instance_t _instance, e2e_buffer& its_buffer); + + /** + * remove bytes from a buffer starting at a specified index. + * + * @param buffer Pointer to the byte buffer. + * @param bufferSize Size of the byte buffer. + * @param startIndex Starting index from where bytes should be erased. + * @param length Number of bytes to erase from the buffer. + * @return true if the operation succeeds, false otherwise. + */ + bool erase_bytes(byte_t *buffer, size_t bufferSize, size_t startIndex, size_t length); + + void reduce_msg_length(byte_t *buffer, length_t& bufferSize,length_t reduceBy); + #ifdef VSOMEIP_ENABLE_DEFAULT_EVENT_CACHING bool has_subscribed_eventgroup( service_t _service, instance_t _instance) const; diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp index 71240a926..df5fa29ea 100644 --- a/implementation/routing/src/routing_manager_impl.cpp +++ b/implementation/routing/src/routing_manager_impl.cpp @@ -54,7 +54,7 @@ #include "../../tracing/include/connector_impl.hpp" #endif -#ifndef ANDROID +#ifdef ENABLE_E2E_FEATURE #include "../../e2e_protection/include/buffer/buffer.hpp" #include "../../e2e_protection/include/e2exf/config.hpp" @@ -170,7 +170,7 @@ void routing_manager_impl::init() { } } -#ifndef ANDROID +#ifdef ENABLE_E2E_FEATURE if( configuration_->is_e2e_enabled()) { VSOMEIP_INFO << "E2E protection enabled."; @@ -942,30 +942,21 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, is_sent = deliver_message(_data, _size, _instance, _reliable, VSOMEIP_ROUTING_CLIENT, _sec_client, _status_check); } else { +#ifdef ENABLE_E2E_FEATURE e2e_buffer its_buffer; - if (e2e_provider_) { if ( !is_service_discovery) { service_t its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); method_t its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); -#ifndef ANDROID - if (e2e_provider_->is_protected({its_service, its_method})) { - // Find out where the protected area starts - size_t its_base = e2e_provider_->get_protection_base({its_service, its_method}); - - // Build a corresponding buffer - its_buffer.assign(_data + its_base, _data + _size); - e2e_provider_->protect({ its_service, its_method }, its_buffer, _instance); - - // Prepend header - its_buffer.insert(its_buffer.begin(), _data, _data + its_base); - - _data = its_buffer.data(); - } -#endif + if (e2e_provider_->is_protected({its_service, its_method})) { + if (!apply_e2e_protection(&_data, _size, its_service, its_method, _instance, its_buffer)) { + VSOMEIP_ERROR << __func__ << ":" << __LINE__ << ": apply_e2e_protection failed"; + } + } } } +#endif if (is_request) { its_target = ep_mgr_impl_->find_or_create_remote_client( its_service, _instance, _reliable); @@ -1130,21 +1121,19 @@ bool routing_manager_impl::send_to( if (its_serializer->serialize(_message.get())) { const byte_t *its_data = its_serializer->get_data(); length_t its_size = its_serializer->get_size(); +#ifdef ENABLE_E2E_FEATURE e2e_buffer its_buffer; if (e2e_provider_) { service_t its_service = bithelper::read_uint16_be(&its_data[VSOMEIP_SERVICE_POS_MIN]); method_t its_method = bithelper::read_uint16_be(&its_data[VSOMEIP_METHOD_POS_MIN]); -#ifndef ANDROID + if (e2e_provider_->is_protected({its_service, its_method})) { - auto its_base = e2e_provider_->get_protection_base({its_service, its_method}); - its_buffer.assign(its_data + its_base, its_data + its_size); - e2e_provider_->protect({its_service, its_method}, its_buffer, _message->get_instance()); - its_buffer.insert(its_buffer.begin(), its_data, its_data + its_base); - its_data = its_buffer.data(); - } -#endif + if (!apply_e2e_protection(&its_data, its_size, its_service, its_method, _message->get_instance(), its_buffer)) { + VSOMEIP_ERROR << __func__ << ":" << __LINE__ << ": apply_e2e_protection failed"; + } + } } - +#endif uint8_t its_client[2] = {0}; bithelper::write_uint16_le(_client, its_client); const_cast(its_data)[VSOMEIP_CLIENT_POS_MIN] = its_client[1]; @@ -1581,22 +1570,50 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, } } } +#ifdef ENABLE_E2E_FEATURE if (e2e_provider_) { its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); -#ifndef ANDROID + const client_t its_client = bithelper::read_uint16_be(&_data[VSOMEIP_CLIENT_POS_MIN]); + const session_t its_session = bithelper::read_uint16_be(&_data[VSOMEIP_SESSION_POS_MIN]); if (e2e_provider_->is_checked({its_service, its_method})) { auto its_base = e2e_provider_->get_protection_base({its_service, its_method}); - e2e_buffer its_buffer(_data + its_base, _data + _size); + e2e_buffer its_buffer; + its_buffer.assign(_data + its_base, _data + _size); e2e_provider_->check({its_service, its_method}, its_buffer, its_instance, its_check_status); if (its_check_status != e2e::profile_interface::generic_check_status::E2E_OK) { - VSOMEIP_INFO << "E2E protection: CRC check failed for service: " + boost::system::error_code ec; + VSOMEIP_ERROR + << "E2E protection: CRC check failed for service: [" + << std::hex << std::setfill('0') << std::setw(4) + << its_service << "." << std::setw(4) + << its_instance << "." << std::setw(4) << its_method + << "." << std::setw(4) << its_client << "." + << std::setw(4) << its_session + << "] from: " << _remote_address.to_string(ec) + << ":" << std::dec << _remote_port; + return; + } + else { + VSOMEIP_INFO << "E2E protection: CRC check passed for service: " << std::hex << its_service << " method: " << its_method; + if (e2e_provider_->should_remove_e2e_header({its_service, its_method})) + { + length_t header_len_ = 0, crc_offset_ = 0; + e2e_provider_->get_header_offset_and_length({its_service, its_method}, crc_offset_, header_len_); + if (header_len_) + { + if (erase_bytes(const_cast(_data), _size, its_base + crc_offset_, header_len_)) + { + reduce_msg_length(const_cast(_data), _size, header_len_); + } + } + } } } -#endif } +#endif // ACL check message if(!is_acl_message_allowed(_receiver, its_service, its_instance, _remote_address)) { @@ -5085,4 +5102,69 @@ routing_manager_impl::remove_subscriptions(port_t _local_port, } } +bool routing_manager_impl::erase_bytes(byte_t *buffer, size_t bufferSize, + size_t startIndex, size_t length) { + if (bufferSize < (startIndex + length)) { + return false; + } + if (bufferSize == (startIndex + length )) { + memset(&buffer[startIndex], 0, length ); + return true; + } + memmove(&buffer[startIndex], &buffer[startIndex + length ], bufferSize - startIndex - length ); + memset(&buffer[bufferSize - length ], 0, length ); + return true; +} + +void routing_manager_impl::reduce_msg_length(byte_t *buffer, length_t& bufferSize, + length_t reduceBy) { + if(!reduceBy){ + return; + } + length_t its_length = bithelper::read_uint32_be(&buffer[VSOMEIP_LENGTH_POS_MIN]); + if (its_length > reduceBy) { + *(reinterpret_cast(&(buffer)[VSOMEIP_LENGTH_POS_MIN])) = + htonl(static_cast(its_length - reduceBy)); + bufferSize -= reduceBy; + } +} + +bool routing_manager_impl::apply_e2e_protection(const byte_t **_data, length_t &_size, + service_t _service, method_t _method, + instance_t _instance, e2e_buffer& its_buffer) { + length_t crc_offset_ = 0; + length_t e2e_header_len_ = 0; + + e2e_provider_->get_header_offset_and_length ({_service, _method}, crc_offset_, e2e_header_len_); + + if (!e2e_header_len_) { + VSOMEIP_ERROR << __func__ << ":" << __LINE__ << ": No E2E header available"; + return false; // No header available + } + + length_t payload_length = bithelper::read_uint32_be(*_data + VSOMEIP_LENGTH_POS_MIN); + length_t payload_msg_length = static_cast(_size - VSOMEIP_PAYLOAD_POS); + size_t protection_base = e2e_provider_->get_protection_base({_service, _method}); + + //Resizing to hold the message data (CRC,E2E header,payload) and initializing it with zeros + its_buffer.assign(crc_offset_ + e2e_header_len_ + payload_msg_length, 0); + // Copy data before E2E header (CRC etc.) to the beginning of the buffer + std::copy (*_data + protection_base, *_data + protection_base + crc_offset_, its_buffer.begin()); + // Copy payload data after E2E header to the new buffer + std::copy (*_data + protection_base + crc_offset_, *_data + _size, its_buffer.begin() + crc_offset_ + e2e_header_len_); + + e2e_provider_->protect({_service, _method}, its_buffer, _instance); + + //Prepend header + its_buffer.insert(its_buffer.begin(), *_data, *_data + protection_base); + + // Update Message Length + payload_length += e2e_header_len_; + *(reinterpret_cast(&its_buffer[VSOMEIP_LENGTH_POS_MIN])) = htonl(payload_length); + + _size = static_cast (its_buffer.size()); + *_data = its_buffer.data(); + return true; +} + } // namespace vsomeip_v3