// Copyright (C) 2014-2018 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 #include "../include/constants.hpp" #include "../include/eventgroupentry_impl.hpp" #include "../../message/include/deserializer.hpp" #include "../../message/include/serializer.hpp" #include "../include/ipv4_option_impl.hpp" #include "../include/ipv6_option_impl.hpp" #include "../include/selective_option_impl.hpp" namespace vsomeip_v3 { namespace sd { eventgroupentry_impl::eventgroupentry_impl() : reserved_(0) { eventgroup_ = 0xFFFF; counter_ = 0; } eventgroupentry_impl::eventgroupentry_impl(const eventgroupentry_impl &_entry) : entry_impl(_entry), reserved_(0) { eventgroup_ = _entry.eventgroup_; counter_ = _entry.counter_; } eventgroupentry_impl::~eventgroupentry_impl() { } eventgroup_t eventgroupentry_impl::get_eventgroup() const { return eventgroup_; } void eventgroupentry_impl::set_eventgroup(eventgroup_t _eventgroup) { eventgroup_ = _eventgroup; } uint16_t eventgroupentry_impl::get_reserved() const { return reserved_; } void eventgroupentry_impl::set_reserved(uint16_t _reserved) { reserved_ = _reserved; } uint8_t eventgroupentry_impl::get_counter() const { return counter_; } void eventgroupentry_impl::set_counter(uint8_t _counter) { counter_ = _counter; } bool eventgroupentry_impl::serialize(vsomeip_v3::serializer *_to) const { bool is_successful = entry_impl::serialize(_to); is_successful = is_successful && _to->serialize(major_version_); is_successful = is_successful && _to->serialize(static_cast(ttl_), true); is_successful = is_successful && _to->serialize(protocol::reserved_word); is_successful = is_successful && _to->serialize(static_cast(eventgroup_)); return is_successful; } bool eventgroupentry_impl::deserialize(vsomeip_v3::deserializer *_from) { bool is_successful = entry_impl::deserialize(_from); uint8_t tmp_major_version(0); is_successful = is_successful && _from->deserialize(tmp_major_version); major_version_ = static_cast(tmp_major_version); uint32_t its_ttl(0); is_successful = is_successful && _from->deserialize(its_ttl, true); ttl_ = static_cast(its_ttl); is_successful = is_successful && _from->deserialize(reserved_); uint16_t its_eventgroup = 0; is_successful = is_successful && _from->deserialize(its_eventgroup); eventgroup_ = static_cast(its_eventgroup); return is_successful; } bool eventgroupentry_impl::matches(const eventgroupentry_impl& _other, const message_impl::options_t& _options) const { if (service_ == _other.service_ && instance_ == _other.instance_ && eventgroup_ == _other.eventgroup_ && major_version_ == _other.major_version_ && counter_ == _other.counter_) { // Check, whether options are identical if (index1_ == _other.index1_ && index2_ == _other.index2_ && num_options_[0] == _other.num_options_[0] && num_options_[1] == _other.num_options_[1]) { return true; } // check if entries reference options at different indexes but the // options itself are identical // check if number of options referenced is the same if (num_options_[0] + num_options_[1] != _other.num_options_[0] + _other.num_options_[1] || num_options_[0] + num_options_[1] == 0) { return false; } // read out ip options of current and _other std::vector> its_options_current; std::vector> its_options_other; const std::size_t its_options_size = _options.size(); for (const auto option_run : {0,1}) { for (const auto option_index : options_[option_run]) { if (its_options_size > option_index) { switch (_options[option_index]->get_type()) { case option_type_e::IP4_ENDPOINT: its_options_current.push_back( std::static_pointer_cast( _options[option_index])); break; case option_type_e::IP6_ENDPOINT: its_options_current.push_back( std::static_pointer_cast( _options[option_index])); break; default: break; } } } for (const auto option_index : _other.options_[option_run]) { if (its_options_size > option_index) { switch (_options[option_index]->get_type()) { case option_type_e::IP4_ENDPOINT: its_options_other.push_back( std::static_pointer_cast( _options[option_index])); break; case option_type_e::IP6_ENDPOINT: its_options_other.push_back( std::static_pointer_cast( _options[option_index])); break; default: break; } } } } if (!its_options_current.size() || !its_options_other.size()) { return false; } // search every option of current in other for (const auto& c : its_options_current) { bool found(false); for (const auto& o : its_options_other) { if (*c == *o) { switch (c->get_type()) { case option_type_e::IP4_ENDPOINT: if (static_cast(c.get())->get_address() == static_cast(o.get())->get_address()) { found = true; } break; case option_type_e::IP6_ENDPOINT: if (static_cast(c.get())->get_address() == static_cast(o.get())->get_address()) { found = true; } break; default: break; } } if (found) { break; } } if (!found) { return false; } } return true; } return false; } void eventgroupentry_impl::add_target( const std::shared_ptr &_target) { if (_target->is_reliable()) { target_reliable_ = _target; } else { target_unreliable_ = _target; } } std::shared_ptr eventgroupentry_impl::get_target( bool _reliable) const { return _reliable ? target_reliable_ : target_unreliable_; } std::shared_ptr eventgroupentry_impl::get_selective_option() const { for (const auto i : {0, 1}) { for (const auto j : options_[i]) { auto its_option = std::dynamic_pointer_cast< selective_option_impl>(owner_->get_option(j)); if (its_option) return its_option; } } return nullptr; } } // namespace sd } // namespace vsomeip_v3