1 // Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
2 // This Source Code Form is subject to the terms of the Mozilla Public
3 // License, v. 2.0. If a copy of the MPL was not distributed with this
4 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 
6 #include <iomanip>
7 #include <sstream>
8 
9 #include <vsomeip/internal/logger.hpp>
10 
11 #include "../../../../e2e_protection/include/e2e/profile/e2e_provider_impl.hpp"
12 
13 #include "../../../../e2e_protection/include/e2e/profile/profile01/checker.hpp"
14 #include "../../../../e2e_protection/include/e2e/profile/profile01/profile_01.hpp"
15 #include "../../../../e2e_protection/include/e2e/profile/profile01/protector.hpp"
16 
17 #include "../../../../e2e_protection/include/e2e/profile/profile04/checker.hpp"
18 #include "../../../../e2e_protection/include/e2e/profile/profile04/profile_04.hpp"
19 #include "../../../../e2e_protection/include/e2e/profile/profile04/protector.hpp"
20 
21 #include "../../../../e2e_protection/include/e2e/profile/profile_custom/checker.hpp"
22 #include "../../../../e2e_protection/include/e2e/profile/profile_custom/profile_custom.hpp"
23 #include "../../../../e2e_protection/include/e2e/profile/profile_custom/protector.hpp"
24 
25 namespace {
26 
27 template<typename value_t>
read_value_from_config(const std::shared_ptr<vsomeip_v3::cfg::e2e> & _config,const std::string & _name,value_t _default_value=value_t ())28 value_t read_value_from_config(const std::shared_ptr<vsomeip_v3::cfg::e2e> &_config,
29                                const std::string &_name,
30                                value_t _default_value = value_t()) {
31 
32     if (_config && _config->custom_parameters.count(_name)) {
33 
34         std::stringstream its_converter;
35         std::string its_value(_config->custom_parameters[_name]);
36 
37         if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') {
38             its_converter << std::hex << its_value;
39         } else {
40             its_converter << std::dec << its_value;
41         }
42 
43         value_t its_converted_value;
44         its_converter >> its_converted_value;
45         return its_converted_value;
46     }
47 
48     return _default_value;
49 }
50 
51 } // namespace
52 
53 
54 VSOMEIP_PLUGIN(vsomeip_v3::e2e::e2e_provider_impl)
55 
56 namespace vsomeip_v3 {
57 namespace e2e {
58 
e2e_provider_impl()59 e2e_provider_impl::e2e_provider_impl()
60     : plugin_impl("vsomeip e2e plugin", 1, plugin_type_e::APPLICATION_PLUGIN)
61 {
62 }
63 
~e2e_provider_impl()64 e2e_provider_impl::~e2e_provider_impl()
65 {
66 }
67 
add_configuration(std::shared_ptr<cfg::e2e> config)68 bool e2e_provider_impl::add_configuration(std::shared_ptr<cfg::e2e> config)
69 {
70     if (config->profile == "CRC8" || config->profile == "P01") {
71         process_e2e_profile<profile01::profile_config, profile01::profile_01_checker, profile01::protector>(config);
72         return true;
73     }
74 
75     if (config->profile == "CRC32" || config->profile == "CSTM") {
76         process_e2e_profile<profile_custom::profile_config, profile_custom::profile_custom_checker, profile_custom::protector>(config);
77         return true;
78     }
79 
80     if (config->profile == "P04") {
81         process_e2e_profile<profile04::profile_config, profile04::profile_04_checker, profile04::protector>(config);
82         return true;
83     }
84 
85     return false;
86 }
87 
is_protected(e2exf::data_identifier_t id) const88 bool e2e_provider_impl::is_protected(e2exf::data_identifier_t id) const
89 {
90     return custom_protectors_.count(id) > 0;
91 }
92 
is_checked(e2exf::data_identifier_t id) const93 bool e2e_provider_impl::is_checked(e2exf::data_identifier_t id) const
94 {
95     return custom_checkers_.count(id) > 0;
96 }
97 
get_protection_base(e2exf::data_identifier_t id) const98 std::size_t e2e_provider_impl::get_protection_base(e2exf::data_identifier_t id) const
99 {
100     const auto found_base = custom_bases_.find(id);
101     if (found_base != custom_bases_.end())
102         return (found_base->second);
103 
104     return (0);
105 }
106 
protect(e2exf::data_identifier_t id,e2e_buffer & _buffer,instance_t _instance)107 void e2e_provider_impl::protect(e2exf::data_identifier_t id, e2e_buffer &_buffer,
108         instance_t _instance)
109 {
110     auto protector = custom_protectors_.find(id);
111     if(protector != custom_protectors_.end()) {
112         protector->second->protect(_buffer, _instance);
113     }
114 }
115 
check(e2exf::data_identifier_t id,const e2e_buffer & _buffer,instance_t _instance,profile_interface::check_status_t & _generic_check_status)116 void e2e_provider_impl::check(e2exf::data_identifier_t id,
117         const e2e_buffer &_buffer, instance_t _instance,
118         profile_interface::check_status_t &_generic_check_status)
119 {
120     auto checker = custom_checkers_.find(id);
121     if(checker != custom_checkers_.end()) {
122         checker->second->check(_buffer, _instance, _generic_check_status);
123     }
124 }
125 
126 template<>
127 vsomeip_v3::e2e::profile01::profile_config
make_e2e_profile_config(const std::shared_ptr<cfg::e2e> & _config)128 e2e_provider_impl::make_e2e_profile_config(const std::shared_ptr<cfg::e2e> &_config) {
129     uint16_t data_id = read_value_from_config<uint16_t>(_config, "data_id");
130     uint16_t crc_offset = read_value_from_config<uint16_t>(_config, "crc_offset");
131     uint16_t data_length = read_value_from_config<uint16_t>(_config, "data_length");
132 
133     // counter field behind CRC8
134     uint16_t counter_offset = read_value_from_config<uint16_t>(_config, "counter_offset", 8);
135 
136     // data id nibble behind 4 bit counter value
137     uint16_t data_id_nibble_offset = read_value_from_config<uint16_t>(_config, "data_id_nibble_offset", 12);
138 
139     e2e::profile01::p01_data_id_mode data_id_mode =
140         static_cast<e2e::profile01::p01_data_id_mode>(
141             read_value_from_config<uint16_t>(_config, "data_id_mode"));
142 
143     return e2e::profile01::profile_config(crc_offset, data_id, data_id_mode,
144         data_length, counter_offset, data_id_nibble_offset);
145 }
146 
147 template<>
148 vsomeip_v3::e2e::profile04::profile_config
make_e2e_profile_config(const std::shared_ptr<cfg::e2e> & _config)149 e2e_provider_impl::make_e2e_profile_config(const std::shared_ptr<cfg::e2e> &_config) {
150 
151     uint32_t data_id = read_value_from_config<uint32_t>(_config, "data_id");
152 
153     size_t offset = read_value_from_config<size_t>(_config, "crc_offset");
154     if (offset % 8)
155         VSOMEIP_ERROR << "Offset in E2E P04 configuration must be multiple of 8"
156             " (" << offset << ")";
157     offset /= 8;
158 
159     size_t min_data_length = read_value_from_config<size_t>(_config,
160             "min_data_length", 0);
161 
162     size_t max_data_length = read_value_from_config<size_t>(_config,
163             "max_data_length", size_t(0xffff));
164 
165     uint16_t max_delta_counter = read_value_from_config<uint16_t>(_config,
166             "max_delta_counter", uint16_t(0xffff));
167 
168     return e2e::profile04::profile_config(data_id, offset,
169             min_data_length, max_data_length, max_delta_counter);
170 }
171 
172 template<>
173 e2e::profile_custom::profile_config
make_e2e_profile_config(const std::shared_ptr<cfg::e2e> & config)174 e2e_provider_impl::make_e2e_profile_config(const std::shared_ptr<cfg::e2e>& config) {
175     uint16_t crc_offset = read_value_from_config<uint16_t>(config, "crc_offset");
176     return e2e::profile_custom::profile_config(crc_offset);
177 }
178 
179 } // namespace e2e
180 } // namespace vsomeip_v3
181