Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

E2E: Invent support for E2E Profile 05. #589

Merged
merged 2 commits into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions implementation/e2e_protection/include/buffer/buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class buffer_view {

const uint8_t *end(void) const { return data_ptr_ + data_length_; }

size_t data_length(void) const { return data_length_; }

private:
const uint8_t *data_ptr_;
size_t data_length_;
Expand Down
3 changes: 3 additions & 0 deletions implementation/e2e_protection/include/crc/crc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class e2e_crc {
const uint8_t _start_value = 0x00U);
static uint32_t calculate_profile_04(buffer_view _buffer_view,
const uint32_t _start_value = 0x00000000U);
static uint16_t calculate_profile_05(buffer_view _buffer_view,
const uint16_t _start_value = 0xFFFFU);
static uint64_t calculate_profile_07(buffer_view _buffer_view,
const uint64_t _start_value = 0x0000000000000000U);

Expand All @@ -25,6 +27,7 @@ class e2e_crc {
private:
static const uint8_t lookup_table_profile_01_[256];
static const uint32_t lookup_table_profile_04_[256];
static const uint16_t lookup_table_profile_05_[256];
static const uint64_t lookup_table_profile_07_[256];
static const uint32_t lookup_table_profile_custom_[256];

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
// 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/.

#ifndef VSOMEIP_V3_E2E_PROFILE05_CHECKER_HPP
#define VSOMEIP_V3_E2E_PROFILE05_CHECKER_HPP

#include <map>

#include "../profile05/profile_05.hpp"
#include "../profile_interface/checker.hpp"

namespace vsomeip_v3 {
namespace e2e {
namespace profile05 {

class profile_05_checker final : public e2e::profile_interface::checker {

public:
profile_05_checker(void) = delete;

// [SWS_E2E_00389] initialize state
explicit profile_05_checker(const profile_config &_config) :
config_(_config) {}

void check(const e2e_buffer &_buffer, instance_t _instance,
e2e::profile_interface::check_status_t &_generic_check_status) override final;

private:
bool verify_input(const e2e_buffer &_buffer) const;
bool verify_counter(instance_t _instance, uint8_t _received_counter);

bool read_8(const e2e_buffer &_buffer, uint8_t &_data, size_t _index) const;
bool read_16(const e2e_buffer &_buffer, uint16_t &_data, size_t _index) const;

std::mutex check_mutex_;

profile_config config_;
std::map<instance_t, uint8_t> counter_;
};

} // namespace profile_05
} // namespace e2e
} // namespace vsomeip_v3

#endif // VSOMEIP_V3_E2E_PROFILE05_CHECKER_HPP
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
// 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/.

#ifndef VSOMEIP_V3_E2E_PROFILE05_PROFILE05_HPP
#define VSOMEIP_V3_E2E_PROFILE05_PROFILE05_HPP

#include <cstdint>

#include <vsomeip/defines.hpp>

#include "../../../buffer/buffer.hpp"

// The MSB of the dataID is the instance identifier.
// Therefore, the instance identifier must fit into a single byte.
#define VSOMEIP_E2E_PROFILE05_MAX_INSTANCE 0x00ff

namespace vsomeip_v3 {
namespace e2e {
namespace profile05 {

struct profile_config;

class profile_05 {
public:
static uint16_t compute_crc(const profile_config &_config, const e2e_buffer &_buffer);

static bool is_buffer_length_valid(const profile_config &_config, const e2e_buffer &_buffer);
};

struct profile_config {
profile_config() = delete;

profile_config(uint32_t _data_id, uint16_t _data_length,
size_t _offset, uint16_t _max_delta_counter)

: data_id_(_data_id), data_length_(_data_length),
offset_(_offset), 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;

uint32_t data_id_;
uint16_t data_length_;
size_t offset_; // This must be configured in bit but as a multiple of 8.
// As we must use it as an index, we do the math once at
// configuration time and use the correct data type here.
// Thus, this value is always the byte where the CRC starts.
uint16_t max_delta_counter_;

// SOME/IP base
size_t base_;
};

} // namespace profile_05
} // namespace e2e
} // namespace vsomeip_v3

#endif // VSOMEIP_V3_E2E_PROFILE05_PROFILE05_HPP
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
// 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/.

#ifndef VSOMEIP_V3_E2E_PROFILE05_PROTECTOR_HPP
#define VSOMEIP_V3_E2E_PROFILE05_PROTECTOR_HPP

#include <map>
#include <mutex>

#include "../profile05/profile_05.hpp"
#include "../profile_interface/protector.hpp"

namespace vsomeip_v3 {
namespace e2e {
namespace profile05 {

class protector final : public e2e::profile_interface::protector {
public:
protector(void) = delete;

explicit protector(const profile_config &_config)
: config_(_config) {}

void protect(e2e_buffer &_buffer, instance_t _instance) override final;

private:
bool verify_inputs(e2e_buffer &_buffer);
uint8_t get_counter(instance_t _instance) const;
void increment_counter(instance_t _instance);

void write_counter(e2e_buffer &_buffer, uint8_t _data, size_t _index);
void write_crc(e2e_buffer &_buffer, uint16_t _data, size_t _index);

private:
profile_config config_;
std::map<instance_t, uint8_t> counter_;
std::mutex protect_mutex_;
};

} // namespace profile_05
} // namespace e2e
} // namespace vsomeip_v3

#endif // VSOMEIP_V3_E2E_PROFILE05_PROTECTOR_HPP
57 changes: 57 additions & 0 deletions implementation/e2e_protection/src/crc/crc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,63 @@ const uint32_t e2e_crc::lookup_table_profile_04_[256] = {
0x0C8DF352U, 0x3C08FCA7U, 0x6D87ECB8U, 0x5D02E34DU, 0xCE99CC86U, 0xFE1CC373U, 0xAF93D36CU, 0x9F16DC99U
};


/**
* Calculates the CRC16 over the provided range.
*/
uint16_t e2e_crc::calculate_profile_05(buffer_view _buffer_view, const uint16_t _start_value) {
const uint8_t * buffer = _buffer_view.begin();
uint32_t buffer_length = (uint32_t)_buffer_view.data_length();
uint16_t crc = _start_value;

/* Process all data (byte wise) */
for (uint32_t i = 0; i < buffer_length; ++i) {
/* Process one byte of data */
crc = lookup_table_profile_05_[((uint8_t)(crc >> 8U)) ^ buffer[i]] ^
((uint16_t)(crc << 8U));
}

/* Specified final XOR value for CRC16 is 0, no need to actually xor anything here */
return crc;
}


const uint16_t e2e_crc::lookup_table_profile_05_[256] = {
0x0000U, 0x1021U, 0x2042U, 0x3063U, 0x4084U, 0x50A5U, 0x60C6U, 0x70E7U,
0x8108U, 0x9129U, 0xA14AU, 0xB16BU, 0xC18CU, 0xD1ADU, 0xE1CEU, 0xF1EFU,
0x1231U, 0x0210U, 0x3273U, 0x2252U, 0x52B5U, 0x4294U, 0x72F7U, 0x62D6U,
0x9339U, 0x8318U, 0xB37BU, 0xA35AU, 0xD3BDU, 0xC39CU, 0xF3FFU, 0xE3DEU,
0x2462U, 0x3443U, 0x0420U, 0x1401U, 0x64E6U, 0x74C7U, 0x44A4U, 0x5485U,
0xA56AU, 0xB54BU, 0x8528U, 0x9509U, 0xE5EEU, 0xF5CFU, 0xC5ACU, 0xD58DU,
0x3653U, 0x2672U, 0x1611U, 0x0630U, 0x76D7U, 0x66F6U, 0x5695U, 0x46B4U,
0xB75BU, 0xA77AU, 0x9719U, 0x8738U, 0xF7DFU, 0xE7FEU, 0xD79DU, 0xC7BCU,
0x48C4U, 0x58E5U, 0x6886U, 0x78A7U, 0x0840U, 0x1861U, 0x2802U, 0x3823U,
0xC9CCU, 0xD9EDU, 0xE98EU, 0xF9AFU, 0x8948U, 0x9969U, 0xA90AU, 0xB92BU,
0x5AF5U, 0x4AD4U, 0x7AB7U, 0x6A96U, 0x1A71U, 0x0A50U, 0x3A33U, 0x2A12U,
0xDBFDU, 0xCBDCU, 0xFBBFU, 0xEB9EU, 0x9B79U, 0x8B58U, 0xBB3BU, 0xAB1AU,
0x6CA6U, 0x7C87U, 0x4CE4U, 0x5CC5U, 0x2C22U, 0x3C03U, 0x0C60U, 0x1C41U,
0xEDAEU, 0xFD8FU, 0xCDECU, 0xDDCDU, 0xAD2AU, 0xBD0BU, 0x8D68U, 0x9D49U,
0x7E97U, 0x6EB6U, 0x5ED5U, 0x4EF4U, 0x3E13U, 0x2E32U, 0x1E51U, 0x0E70U,
0xFF9FU, 0xEFBEU, 0xDFDDU, 0xCFFCU, 0xBF1BU, 0xAF3AU, 0x9F59U, 0x8F78U,
0x9188U, 0x81A9U, 0xB1CAU, 0xA1EBU, 0xD10CU, 0xC12DU, 0xF14EU, 0xE16FU,
0x1080U, 0x00A1U, 0x30C2U, 0x20E3U, 0x5004U, 0x4025U, 0x7046U, 0x6067U,
0x83B9U, 0x9398U, 0xA3FBU, 0xB3DAU, 0xC33DU, 0xD31CU, 0xE37FU, 0xF35EU,
0x02B1U, 0x1290U, 0x22F3U, 0x32D2U, 0x4235U, 0x5214U, 0x6277U, 0x7256U,
0xB5EAU, 0xA5CBU, 0x95A8U, 0x8589U, 0xF56EU, 0xE54FU, 0xD52CU, 0xC50DU,
0x34E2U, 0x24C3U, 0x14A0U, 0x0481U, 0x7466U, 0x6447U, 0x5424U, 0x4405U,
0xA7DBU, 0xB7FAU, 0x8799U, 0x97B8U, 0xE75FU, 0xF77EU, 0xC71DU, 0xD73CU,
0x26D3U, 0x36F2U, 0x0691U, 0x16B0U, 0x6657U, 0x7676U, 0x4615U, 0x5634U,
0xD94CU, 0xC96DU, 0xF90EU, 0xE92FU, 0x99C8U, 0x89E9U, 0xB98AU, 0xA9ABU,
0x5844U, 0x4865U, 0x7806U, 0x6827U, 0x18C0U, 0x08E1U, 0x3882U, 0x28A3U,
0xCB7DU, 0xDB5CU, 0xEB3FU, 0xFB1EU, 0x8BF9U, 0x9BD8U, 0xABBBU, 0xBB9AU,
0x4A75U, 0x5A54U, 0x6A37U, 0x7A16U, 0x0AF1U, 0x1AD0U, 0x2AB3U, 0x3A92U,
0xFD2EU, 0xED0FU, 0xDD6CU, 0xCD4DU, 0xBDAAU, 0xAD8BU, 0x9DE8U, 0x8DC9U,
0x7C26U, 0x6C07U, 0x5C64U, 0x4C45U, 0x3CA2U, 0x2C83U, 0x1CE0U, 0x0CC1U,
0xEF1FU, 0xFF3EU, 0xCF5DU, 0xDF7CU, 0xAF9BU, 0xBFBAU, 0x8FD9U, 0x9FF8U,
0x6E17U, 0x7E36U, 0x4E55U, 0x5E74U, 0x2E93U, 0x3EB2U, 0x0ED1U, 0x1EF0U
};


/**
* Calculates the CRC over the provided range.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
#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/profile05/checker.hpp"
#include "../../../../e2e_protection/include/e2e/profile/profile05/profile_05.hpp"
#include "../../../../e2e_protection/include/e2e/profile/profile05/protector.hpp"

#include "../../../../e2e_protection/include/e2e/profile/profile_custom/checker.hpp"
#include "../../../../e2e_protection/include/e2e/profile/profile_custom/profile_custom.hpp"
#include "../../../../e2e_protection/include/e2e/profile/profile_custom/protector.hpp"
Expand Down Expand Up @@ -86,6 +90,11 @@ bool e2e_provider_impl::add_configuration(std::shared_ptr<cfg::e2e> config)
return true;
}

if (config->profile == "P05") {
process_e2e_profile<profile05::profile_config, profile05::profile_05_checker, profile05::protector>(config);
return true;
}

if (config->profile == "P07") {
process_e2e_profile<profile07::profile_config, profile07::profile_07_checker, profile07::protector>(config);
return true;
Expand Down Expand Up @@ -178,6 +187,26 @@ e2e_provider_impl::make_e2e_profile_config(const std::shared_ptr<cfg::e2e> &_con
min_data_length, max_data_length, max_delta_counter);
}

template<>
vsomeip_v3::e2e::profile05::profile_config
e2e_provider_impl::make_e2e_profile_config(const std::shared_ptr<cfg::e2e> &_config) {

uint32_t data_id = read_value_from_config<uint32_t>(_config, "data_id");
uint16_t data_length = read_value_from_config<uint16_t>(_config, "data_length");

size_t offset = read_value_from_config<size_t>(_config, "crc_offset");
if (offset % 8)
VSOMEIP_ERROR << "Offset in E2E P05 configuration must be multiple of 8"
" (" << offset << ")";
offset /= 8;

uint16_t max_delta_counter = read_value_from_config<uint16_t>(_config,
"max_delta_counter", uint16_t(0xffff));

return e2e::profile05::profile_config(data_id, data_length,
offset, max_delta_counter);
}

template<>
e2e::profile_custom::profile_config
e2e_provider_impl::make_e2e_profile_config(const std::shared_ptr<cfg::e2e>& config) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
// 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/.

#include <iomanip>

#include <vsomeip/internal/logger.hpp>

#include "../../../../include/e2e/profile/profile05/checker.hpp"
#include "../../../../../utility/include/byteorder.hpp"

namespace vsomeip_v3 {
namespace e2e {
namespace profile05 {

void profile_05_checker::check(const e2e_buffer &_buffer, instance_t _instance,
e2e::profile_interface::check_status_t &_generic_check_status) {

(void)_instance;

std::lock_guard<std::mutex> lock(check_mutex_);
_generic_check_status = e2e::profile_interface::generic_check_status::E2E_ERROR;

if (_instance > VSOMEIP_E2E_PROFILE05_MAX_INSTANCE) {
VSOMEIP_ERROR << "E2E Profile 5 can only be used for instances [1-255]";
return;
}

if (profile_05::is_buffer_length_valid(config_, _buffer)) {
uint8_t its_received_counter;
if (read_8(_buffer, its_received_counter, 2)) {
uint16_t its_received_crc;
if (read_16(_buffer, its_received_crc, 0)) {
uint16_t its_crc = profile_05::compute_crc(config_, _buffer);
if (its_received_crc != its_crc) {
_generic_check_status = e2e::profile_interface::generic_check_status::E2E_WRONG_CRC;
VSOMEIP_ERROR << std::hex << "E2E P05 protection: CRC16 does not match: calculated CRC: "
<< its_crc << " received CRC: " << its_received_crc;
} else {
if (verify_counter(_instance, its_received_counter)) {
_generic_check_status = e2e::profile_interface::generic_check_status::E2E_OK;
}
}
}
}
}
}

bool
profile_05_checker::verify_counter(instance_t _instance, uint8_t _received_counter) {

uint8_t its_delta(0);

auto find_counter = counter_.find(_instance);
if (find_counter != counter_.end()) {
uint8_t its_counter = find_counter->second;
if (its_counter < _received_counter)
its_delta = uint8_t(_received_counter - its_counter);
else
its_delta = uint8_t(uint8_t(0xff) - its_counter + _received_counter);
} else {
counter_[_instance] = _received_counter;
}

return (its_delta <= config_.max_delta_counter_);
}

bool
profile_05_checker::read_8(const e2e_buffer &_buffer,
uint8_t &_data, size_t _index) const {

_data = _buffer[config_.offset_ + _index];
return true;
}

bool
profile_05_checker::read_16(const e2e_buffer &_buffer,
uint16_t &_data, size_t _index) const {

_data = VSOMEIP_BYTES_TO_WORD(_buffer[config_.offset_ + _index + 1],
_buffer[config_.offset_ + _index]);
return true;
}

} // namespace profile01
} // namespace e2e
} // namespace vsomeip_v3
Loading
Loading