1 // Copyright (C) 2014-2018 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 <vsomeip/internal/logger.hpp>
7
8 #include "../include/constants.hpp"
9 #include "../include/eventgroupentry_impl.hpp"
10 #include "../../message/include/deserializer.hpp"
11 #include "../../message/include/serializer.hpp"
12 #include "../include/ipv4_option_impl.hpp"
13 #include "../include/ipv6_option_impl.hpp"
14 #include "../include/selective_option_impl.hpp"
15
16 namespace vsomeip_v3 {
17 namespace sd {
18
eventgroupentry_impl()19 eventgroupentry_impl::eventgroupentry_impl() :
20 reserved_(0) {
21 eventgroup_ = 0xFFFF;
22 counter_ = 0;
23 }
24
eventgroupentry_impl(const eventgroupentry_impl & _entry)25 eventgroupentry_impl::eventgroupentry_impl(const eventgroupentry_impl &_entry)
26 : entry_impl(_entry),
27 reserved_(0) {
28 eventgroup_ = _entry.eventgroup_;
29 counter_ = _entry.counter_;
30 }
31
~eventgroupentry_impl()32 eventgroupentry_impl::~eventgroupentry_impl() {
33 }
34
get_eventgroup() const35 eventgroup_t eventgroupentry_impl::get_eventgroup() const {
36 return eventgroup_;
37 }
38
set_eventgroup(eventgroup_t _eventgroup)39 void eventgroupentry_impl::set_eventgroup(eventgroup_t _eventgroup) {
40 eventgroup_ = _eventgroup;
41 }
42
get_reserved() const43 uint16_t eventgroupentry_impl::get_reserved() const {
44 return reserved_;
45 }
46
set_reserved(uint16_t _reserved)47 void eventgroupentry_impl::set_reserved(uint16_t _reserved) {
48 reserved_ = _reserved;
49 }
50
get_counter() const51 uint8_t eventgroupentry_impl::get_counter() const {
52 return counter_;
53 }
54
set_counter(uint8_t _counter)55 void eventgroupentry_impl::set_counter(uint8_t _counter) {
56 counter_ = _counter;
57 }
58
serialize(vsomeip_v3::serializer * _to) const59 bool eventgroupentry_impl::serialize(vsomeip_v3::serializer *_to) const {
60 bool is_successful = entry_impl::serialize(_to);
61 is_successful = is_successful && _to->serialize(major_version_);
62 is_successful = is_successful
63 && _to->serialize(static_cast<uint32_t>(ttl_), true);
64 is_successful = is_successful
65 && _to->serialize(protocol::reserved_word);
66 is_successful = is_successful
67 && _to->serialize(static_cast<uint16_t>(eventgroup_));
68
69 return is_successful;
70 }
71
deserialize(vsomeip_v3::deserializer * _from)72 bool eventgroupentry_impl::deserialize(vsomeip_v3::deserializer *_from) {
73 bool is_successful = entry_impl::deserialize(_from);
74
75 uint8_t tmp_major_version(0);
76 is_successful = is_successful && _from->deserialize(tmp_major_version);
77 major_version_ = static_cast<major_version_t>(tmp_major_version);
78
79 uint32_t its_ttl(0);
80 is_successful = is_successful && _from->deserialize(its_ttl, true);
81 ttl_ = static_cast<ttl_t>(its_ttl);
82
83 is_successful = is_successful && _from->deserialize(reserved_);
84
85 uint16_t its_eventgroup = 0;
86 is_successful = is_successful && _from->deserialize(its_eventgroup);
87 eventgroup_ = static_cast<eventgroup_t>(its_eventgroup);
88
89 return is_successful;
90 }
91
matches(const eventgroupentry_impl & _other,const message_impl::options_t & _options) const92 bool eventgroupentry_impl::matches(const eventgroupentry_impl& _other,
93 const message_impl::options_t& _options) const {
94 if (service_ == _other.service_
95 && instance_ == _other.instance_
96 && eventgroup_ == _other.eventgroup_
97 && major_version_ == _other.major_version_
98 && counter_ == _other.counter_) {
99
100 // Check, whether options are identical
101 if (index1_ == _other.index1_
102 && index2_ == _other.index2_
103 && num_options_[0] == _other.num_options_[0]
104 && num_options_[1] == _other.num_options_[1]) {
105 return true;
106 }
107
108 // check if entries reference options at different indexes but the
109 // options itself are identical
110 // check if number of options referenced is the same
111 if (num_options_[0] + num_options_[1]
112 != _other.num_options_[0] + _other.num_options_[1] ||
113 num_options_[0] + num_options_[1] == 0) {
114 return false;
115 }
116
117 // read out ip options of current and _other
118 std::vector<std::shared_ptr<ip_option_impl>> its_options_current;
119 std::vector<std::shared_ptr<ip_option_impl>> its_options_other;
120 const std::size_t its_options_size = _options.size();
121 for (const auto& option_run : {0,1}) {
122 for (const auto& option_index : options_[option_run]) {
123 if (its_options_size > option_index) {
124 switch (_options[option_index]->get_type()) {
125 case option_type_e::IP4_ENDPOINT:
126 its_options_current.push_back(
127 std::static_pointer_cast<ipv4_option_impl>(
128 _options[option_index]));
129 break;
130 case option_type_e::IP6_ENDPOINT:
131 its_options_current.push_back(
132 std::static_pointer_cast<ipv6_option_impl>(
133 _options[option_index]));
134 break;
135 default:
136 break;
137 }
138 }
139 }
140 for (const auto& option_index : _other.options_[option_run]) {
141 if (its_options_size > option_index) {
142 switch (_options[option_index]->get_type()) {
143 case option_type_e::IP4_ENDPOINT:
144 its_options_other.push_back(
145 std::static_pointer_cast<ipv4_option_impl>(
146 _options[option_index]));
147 break;
148 case option_type_e::IP6_ENDPOINT:
149 its_options_other.push_back(
150 std::static_pointer_cast<ipv6_option_impl>(
151 _options[option_index]));
152 break;
153 default:
154 break;
155 }
156 }
157 }
158 }
159
160 if (!its_options_current.size() || !its_options_other.size()) {
161 return false;
162 }
163
164 // search every option of current in other
165 for (const auto& c : its_options_current) {
166 bool found(false);
167 for (const auto& o : its_options_other) {
168 if (*c == *o) {
169 switch (c->get_type()) {
170 case option_type_e::IP4_ENDPOINT:
171 if (static_cast<ipv4_option_impl*>(c.get())->get_address()
172 == static_cast<ipv4_option_impl*>(o.get())->get_address()) {
173 found = true;
174 }
175 break;
176 case option_type_e::IP6_ENDPOINT:
177 if (static_cast<ipv6_option_impl*>(c.get())->get_address()
178 == static_cast<ipv6_option_impl*>(o.get())->get_address()) {
179 found = true;
180 }
181 break;
182 default:
183 break;
184 }
185 }
186 if (found) {
187 break;
188 }
189 }
190 if (!found) {
191 return false;
192 }
193 }
194 return true;
195 }
196 return false;
197 }
198
add_target(const std::shared_ptr<endpoint_definition> & _target)199 void eventgroupentry_impl::add_target(
200 const std::shared_ptr<endpoint_definition> &_target) {
201 if (_target->is_reliable()) {
202 target_reliable_ = _target;
203 } else {
204 target_unreliable_ = _target;
205 }
206 }
207
get_target(bool _reliable) const208 std::shared_ptr<endpoint_definition> eventgroupentry_impl::get_target(
209 bool _reliable) const {
210 return _reliable ? target_reliable_ : target_unreliable_;
211 }
212
213 std::shared_ptr<selective_option_impl>
get_selective_option() const214 eventgroupentry_impl::get_selective_option() const {
215 for (const auto& i : {0, 1}) {
216 for (const auto& j : options_[i]) {
217 auto its_option = std::dynamic_pointer_cast<
218 selective_option_impl>(owner_->get_option(j));
219 if (its_option)
220 return its_option;
221 }
222 }
223 return nullptr;
224 }
225
226 } // namespace sd
227 } // namespace vsomeip_v3
228