// 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 "../include/entry_impl.hpp" #include "../include/message_impl.hpp" #include "../../message/include/deserializer.hpp" #include "../../message/include/serializer.hpp" namespace vsomeip_v3 { namespace sd { // TODO: throw exception if this constructor is used entry_impl::entry_impl() { type_ = entry_type_e::UNKNOWN; major_version_ = 0; service_ = 0x0; instance_ = 0x0; ttl_ = 0x0; num_options_[0] = 0; num_options_[1] = 0; index1_ = 0; index2_ = 0; } entry_impl::entry_impl(const entry_impl &_entry) { type_ = _entry.type_; major_version_ = _entry.major_version_; service_ = _entry.service_; instance_ = _entry.instance_; ttl_ = _entry.ttl_; num_options_[0] = _entry.num_options_[0]; num_options_[1] = _entry.num_options_[1]; index1_ = _entry.index1_; index2_ = _entry.index2_; } entry_impl::~entry_impl() { } entry_type_e entry_impl::get_type() const { return type_; } void entry_impl::set_type(entry_type_e _type) { type_ = _type; } service_t entry_impl::get_service() const { return service_; } void entry_impl::set_service(service_t _service) { service_ = _service; } instance_t entry_impl::get_instance() const { return instance_; } void entry_impl::set_instance(instance_t _instance) { instance_ = _instance; } major_version_t entry_impl::get_major_version() const { return major_version_; } void entry_impl::set_major_version(major_version_t _major_version) { major_version_ = _major_version; } ttl_t entry_impl::get_ttl() const { return ttl_; } void entry_impl::set_ttl(ttl_t _ttl) { ttl_ = _ttl; } const std::vector & entry_impl::get_options(uint8_t _run) const { static std::vector invalid_options; if (_run > 0 && _run <= VSOMEIP_MAX_OPTION_RUN) return options_[_run - 1]; return invalid_options; } void entry_impl::assign_option(const std::shared_ptr &_option) { int16_t i = get_owning_message()->get_option_index(_option); if (i > -1 && i < 256) { uint8_t its_index = static_cast(i); if (options_[0].empty() || options_[0][0] == its_index + 1 || options_[0][options_[0].size() - 1] + 1 == its_index) { options_[0].push_back(its_index); std::sort(options_[0].begin(), options_[0].end()); num_options_[0]++; } else if (options_[1].empty() || options_[1][0] == its_index + 1 || options_[1][options_[1].size() - 1] + 1 == its_index) { options_[1].push_back(its_index); std::sort(options_[1].begin(), options_[1].end()); num_options_[1]++; } else { VSOMEIP_WARNING << "Option is not referenced by entries array, maximum number of endpoint options reached!"; } } else { VSOMEIP_ERROR << "Option could not be found."; } } bool entry_impl::serialize(vsomeip_v3::serializer *_to) const { bool is_successful = (0 != _to && _to->serialize(static_cast(type_))); uint8_t index_first_option_run = 0; if (options_[0].size() > 0) index_first_option_run = options_[0][0]; is_successful = is_successful && _to->serialize(index_first_option_run); uint8_t index_second_option_run = 0; if (options_[1].size() > 0) index_second_option_run = options_[1][0]; is_successful = is_successful && _to->serialize(index_second_option_run); uint8_t number_of_options = uint8_t((((uint8_t) options_[0].size()) << 4) | (((uint8_t) options_[1].size()) & 0x0F)); is_successful = is_successful && _to->serialize(number_of_options); is_successful = is_successful && _to->serialize(static_cast(service_)); is_successful = is_successful && _to->serialize(static_cast(instance_)); return is_successful; } bool entry_impl::deserialize(vsomeip_v3::deserializer *_from) { bool is_successful = (0 != _from); uint8_t its_type(0); is_successful = is_successful && _from->deserialize(its_type); type_ = static_cast(its_type); is_successful = is_successful && _from->deserialize(index1_); is_successful = is_successful && _from->deserialize(index2_); uint8_t its_numbers(0); is_successful = is_successful && _from->deserialize(its_numbers); num_options_[0] = uint8_t(its_numbers >> 4); num_options_[1] = uint8_t(its_numbers & 0xF); for (uint16_t i = index1_; i < index1_ + num_options_[0]; ++i) options_[0].push_back((uint8_t)(i)); for (uint16_t i = index2_; i < index2_ + num_options_[1]; ++i) options_[1].push_back((uint8_t)(i)); uint16_t its_id(0); is_successful = is_successful && _from->deserialize(its_id); service_ = static_cast(its_id); is_successful = is_successful && _from->deserialize(its_id); instance_ = static_cast(its_id); return is_successful; } bool entry_impl::is_service_entry() const { return (type_ <= entry_type_e::REQUEST_SERVICE); } bool entry_impl::is_eventgroup_entry() const { return (type_ >= entry_type_e::FIND_EVENT_GROUP && type_ <= entry_type_e::SUBSCRIBE_EVENTGROUP_ACK); } uint8_t entry_impl::get_num_options(uint8_t _run) const { if (_run < 1 || _run > VSOMEIP_MAX_OPTION_RUN) { return 0x0; } return num_options_[_run-1]; } } // namespace sd } // namespace vsomeip_v3