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