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 <algorithm>
7 
8 #include <vsomeip/internal/logger.hpp>
9 
10 #include "../include/entry_impl.hpp"
11 #include "../include/message_impl.hpp"
12 #include "../../message/include/deserializer.hpp"
13 #include "../../message/include/serializer.hpp"
14 
15 namespace vsomeip_v3 {
16 namespace sd {
17 
18 // TODO: throw exception if this constructor is used
entry_impl()19 entry_impl::entry_impl() {
20     type_ = entry_type_e::UNKNOWN;
21     major_version_ = 0;
22     service_ = 0x0;
23     instance_ = 0x0;
24     ttl_ = 0x0;
25     num_options_[0] = 0;
26     num_options_[1] = 0;
27     index1_ = 0;
28     index2_ = 0;
29 }
30 
entry_impl(const entry_impl & _entry)31 entry_impl::entry_impl(const entry_impl &_entry) {
32     type_ = _entry.type_;
33     major_version_ = _entry.major_version_;
34     service_ = _entry.service_;
35     instance_ = _entry.instance_;
36     ttl_ = _entry.ttl_;
37     num_options_[0] = _entry.num_options_[0];
38     num_options_[1] = _entry.num_options_[1];
39     index1_ = _entry.index1_;
40     index2_ = _entry.index2_;
41 }
42 
~entry_impl()43 entry_impl::~entry_impl() {
44 }
45 
get_type() const46 entry_type_e entry_impl::get_type() const {
47     return type_;
48 }
49 
set_type(entry_type_e _type)50 void entry_impl::set_type(entry_type_e _type) {
51     type_ = _type;
52 }
53 
get_service() const54 service_t entry_impl::get_service() const {
55     return service_;
56 }
57 
set_service(service_t _service)58 void entry_impl::set_service(service_t _service) {
59     service_ = _service;
60 }
61 
get_instance() const62 instance_t entry_impl::get_instance() const {
63     return instance_;
64 }
65 
set_instance(instance_t _instance)66 void entry_impl::set_instance(instance_t _instance) {
67     instance_ = _instance;
68 }
69 
get_major_version() const70 major_version_t entry_impl::get_major_version() const {
71     return major_version_;
72 }
73 
set_major_version(major_version_t _major_version)74 void entry_impl::set_major_version(major_version_t _major_version) {
75     major_version_ = _major_version;
76 }
77 
get_ttl() const78 ttl_t entry_impl::get_ttl() const {
79     return ttl_;
80 }
81 
set_ttl(ttl_t _ttl)82 void entry_impl::set_ttl(ttl_t _ttl) {
83     ttl_ = _ttl;
84 }
85 
get_options(uint8_t _run) const86 const std::vector<uint8_t> & entry_impl::get_options(uint8_t _run) const {
87     static std::vector<uint8_t> invalid_options;
88     if (_run > 0 && _run <= VSOMEIP_MAX_OPTION_RUN)
89         return options_[_run - 1];
90 
91     return invalid_options;
92 }
93 
assign_option(const std::shared_ptr<option_impl> & _option)94 void entry_impl::assign_option(const std::shared_ptr<option_impl> &_option) {
95     int16_t i = get_owning_message()->get_option_index(_option);
96     if (i > -1 && i < 256) {
97         uint8_t its_index = static_cast<uint8_t>(i);
98         if (options_[0].empty() ||
99                 options_[0][0] == its_index + 1 ||
100                 options_[0][options_[0].size() - 1] + 1 == its_index) {
101             options_[0].push_back(its_index);
102             std::sort(options_[0].begin(), options_[0].end());
103             num_options_[0]++;
104         } else if (options_[1].empty() ||
105                 options_[1][0] == its_index + 1 ||
106                 options_[1][options_[1].size() - 1] + 1 == its_index) {
107             options_[1].push_back(its_index);
108             std::sort(options_[1].begin(), options_[1].end());
109             num_options_[1]++;
110         } else {
111             VSOMEIP_WARNING << "Option is not referenced by entries array, maximum number of endpoint options reached!";
112         }
113     } else {
114         VSOMEIP_ERROR << "Option could not be found.";
115     }
116 }
117 
serialize(vsomeip_v3::serializer * _to) const118 bool entry_impl::serialize(vsomeip_v3::serializer *_to) const {
119     bool is_successful = (0 != _to
120             && _to->serialize(static_cast<uint8_t>(type_)));
121 
122     uint8_t index_first_option_run = 0;
123     if (options_[0].size() > 0)
124         index_first_option_run = options_[0][0];
125     is_successful = is_successful && _to->serialize(index_first_option_run);
126 
127     uint8_t index_second_option_run = 0;
128     if (options_[1].size() > 0)
129         index_second_option_run = options_[1][0];
130     is_successful = is_successful && _to->serialize(index_second_option_run);
131 
132     uint8_t number_of_options = uint8_t((((uint8_t) options_[0].size()) << 4)
133             | (((uint8_t) options_[1].size()) & 0x0F));
134     is_successful = is_successful && _to->serialize(number_of_options);
135 
136     is_successful = is_successful
137             && _to->serialize(static_cast<uint16_t>(service_));
138 
139     is_successful = is_successful
140             && _to->serialize(static_cast<uint16_t>(instance_));
141 
142     return is_successful;
143 }
144 
deserialize(vsomeip_v3::deserializer * _from)145 bool entry_impl::deserialize(vsomeip_v3::deserializer *_from) {
146     bool is_successful = (0 != _from);
147 
148     uint8_t its_type(0);
149     is_successful = is_successful && _from->deserialize(its_type);
150     type_ = static_cast<entry_type_e>(its_type);
151 
152     is_successful = is_successful && _from->deserialize(index1_);
153 
154     is_successful = is_successful && _from->deserialize(index2_);
155 
156     uint8_t its_numbers(0);
157     is_successful = is_successful && _from->deserialize(its_numbers);
158 
159     num_options_[0] = uint8_t(its_numbers >> 4);
160     num_options_[1] = uint8_t(its_numbers & 0xF);
161 
162     for (uint16_t i = index1_; i < index1_ + num_options_[0]; ++i)
163         options_[0].push_back((uint8_t)(i));
164 
165     for (uint16_t i = index2_; i < index2_ + num_options_[1]; ++i)
166         options_[1].push_back((uint8_t)(i));
167 
168     uint16_t its_id(0);
169     is_successful = is_successful && _from->deserialize(its_id);
170     service_ = static_cast<service_t>(its_id);
171 
172     is_successful = is_successful && _from->deserialize(its_id);
173     instance_ = static_cast<instance_t>(its_id);
174 
175     return is_successful;
176 }
177 
is_service_entry() const178 bool entry_impl::is_service_entry() const {
179     return (type_ <= entry_type_e::REQUEST_SERVICE);
180 }
181 
is_eventgroup_entry() const182 bool entry_impl::is_eventgroup_entry() const {
183     return (type_ >= entry_type_e::FIND_EVENT_GROUP
184             && type_ <= entry_type_e::SUBSCRIBE_EVENTGROUP_ACK);
185 }
186 
get_num_options(uint8_t _run) const187 uint8_t entry_impl::get_num_options(uint8_t _run) const {
188     if (_run < 1 || _run > VSOMEIP_MAX_OPTION_RUN) {
189         return 0x0;
190     }
191     return num_options_[_run-1];
192 }
193 
194 } // namespace sd
195 } // namespace vsomeip_v3
196