1 // Copyright (C) 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 "../include/remote_subscription.hpp"
7
8 #include <vsomeip/internal/logger.hpp>
9
10 namespace vsomeip_v3 {
11
remote_subscription()12 remote_subscription::remote_subscription()
13 : id_(PENDING_SUBSCRIPTION_ID),
14 is_initial_(true),
15 force_initial_events_(false),
16 major_(DEFAULT_MAJOR),
17 ttl_(DEFAULT_TTL),
18 reserved_(0),
19 counter_(0),
20 answers_(1) {
21 }
22
~remote_subscription()23 remote_subscription::~remote_subscription() {
24 }
25
26 bool
operator ==(const remote_subscription & _other) const27 remote_subscription::operator==(
28 const remote_subscription &_other) const {
29 auto own_egi = eventgroupinfo_.lock();
30 auto other_egi = _other.eventgroupinfo_.lock();
31 bool reliable_equal(true);
32 if (reliable_ && _other.reliable_) {
33 reliable_equal = (reliable_ == _other.reliable_);
34 }
35 bool unreliable_equal(true);
36 if (unreliable_ && _other.unreliable_) {
37 unreliable_equal = (unreliable_ == _other.unreliable_);
38 }
39 return (own_egi && other_egi && own_egi == other_egi && unreliable_equal
40 && reliable_equal);
41 }
42
43 bool
equals(const std::shared_ptr<remote_subscription> & _other) const44 remote_subscription::equals(
45 const std::shared_ptr<remote_subscription> &_other) const {
46 return operator ==(*_other);
47 }
48
49 bool
address_equals(const std::shared_ptr<remote_subscription> & _other) const50 remote_subscription::address_equals(
51 const std::shared_ptr<remote_subscription> &_other) const {
52 bool relibale_address_equals(false);
53 bool unrelibale_address_equals(false);
54
55 if (reliable_ && (*_other).reliable_)
56 relibale_address_equals = (reliable_->get_address()
57 == (*_other).reliable_->get_address());
58 if (unreliable_ && (*_other).unreliable_)
59 unrelibale_address_equals = (unreliable_->get_address()
60 == (*_other).unreliable_->get_address());
61 return (relibale_address_equals || unrelibale_address_equals);
62 }
63
64 void
reset(const std::set<client_t> & _clients)65 remote_subscription::reset(const std::set<client_t> &_clients) {
66 auto its_client_state = std::make_pair(
67 remote_subscription_state_e::SUBSCRIPTION_PENDING,
68 std::chrono::steady_clock::time_point());
69 if (_clients.empty()) {
70 clients_[0] = its_client_state;
71 } else {
72 for (const auto &its_client : _clients)
73 clients_[its_client] = its_client_state;
74 }
75 }
76
77 bool
is_initial() const78 remote_subscription::is_initial() const {
79 return is_initial_;
80 }
81
82 void
set_initial(const bool _is_initial)83 remote_subscription::set_initial(const bool _is_initial) {
84 is_initial_ = _is_initial;
85 }
86
87 bool
force_initial_events() const88 remote_subscription::force_initial_events() const {
89 return force_initial_events_;
90 }
91
92 void
set_force_initial_events(const bool _force_initial_events)93 remote_subscription::set_force_initial_events(
94 const bool _force_initial_events) {
95 force_initial_events_ = _force_initial_events;
96 }
97
98 remote_subscription_id_t
get_id() const99 remote_subscription::get_id() const {
100 return id_;
101 }
102
103 void
set_id(const remote_subscription_id_t _id)104 remote_subscription::set_id(const remote_subscription_id_t _id) {
105 id_ = _id;
106 }
107
108 std::shared_ptr<eventgroupinfo>
get_eventgroupinfo() const109 remote_subscription::get_eventgroupinfo() const {
110 return eventgroupinfo_.lock();
111 }
112
113 void
set_eventgroupinfo(const std::shared_ptr<eventgroupinfo> & _info)114 remote_subscription::set_eventgroupinfo(
115 const std::shared_ptr<eventgroupinfo> &_info) {
116 eventgroupinfo_ = _info;
117 }
118
119 ttl_t
get_ttl() const120 remote_subscription::get_ttl() const {
121 return ttl_;
122 }
123
124 void
set_ttl(const ttl_t _ttl)125 remote_subscription::set_ttl(const ttl_t _ttl) {
126 ttl_ = _ttl;
127 }
128
129 uint16_t
get_reserved() const130 remote_subscription::get_reserved() const {
131 return reserved_;
132 }
133
134 void
set_reserved(const uint16_t _reserved)135 remote_subscription::set_reserved(const uint16_t _reserved) {
136 reserved_ = _reserved;
137 }
138
139 uint8_t
get_counter() const140 remote_subscription::get_counter() const {
141 return counter_;
142 }
143
144 void
set_counter(uint8_t _counter)145 remote_subscription::set_counter(uint8_t _counter) {
146 counter_ = _counter;
147 }
148
149 std::set<client_t>
get_clients() const150 remote_subscription::get_clients() const {
151 std::lock_guard<std::mutex> its_lock(mutex_);
152 std::set<client_t> its_clients;
153 for (const auto &its_item : clients_)
154 its_clients.insert(its_item.first);
155 return its_clients;
156 }
157
158 bool
has_client() const159 remote_subscription::has_client() const {
160 std::lock_guard<std::mutex> its_lock(mutex_);
161 return (clients_.size() > 0);
162 }
163
164 bool
has_client(const client_t _client) const165 remote_subscription::has_client(const client_t _client) const {
166 std::lock_guard<std::mutex> its_lock(mutex_);
167 return (clients_.find(_client) != clients_.end());
168 }
169
170 void
remove_client(const client_t _client)171 remote_subscription::remove_client(const client_t _client) {
172 std::lock_guard<std::mutex> its_lock(mutex_);
173 clients_.erase(_client);
174 }
175
176 remote_subscription_state_e
get_client_state(const client_t _client) const177 remote_subscription::get_client_state(const client_t _client) const {
178 std::lock_guard<std::mutex> its_lock(mutex_);
179 auto found_client = clients_.find(_client);
180 if (found_client != clients_.end()) {
181 return found_client->second.first;
182 }
183 return remote_subscription_state_e::SUBSCRIPTION_UNKNOWN;
184 }
185
186 void
set_client_state(const client_t _client,remote_subscription_state_e _state)187 remote_subscription::set_client_state(const client_t _client,
188 remote_subscription_state_e _state) {
189 std::lock_guard<std::mutex> its_lock(mutex_);
190 auto found_item = clients_.find(_client);
191 if (found_item != clients_.end()) {
192 found_item->second.first = _state;
193 if (found_item->second.second == std::chrono::steady_clock::time_point()
194 && (_state == remote_subscription_state_e::SUBSCRIPTION_ACKED
195 || _state == remote_subscription_state_e::SUBSCRIPTION_NACKED)) {
196 found_item->second.second = std::chrono::steady_clock::now()
197 + std::chrono::seconds(ttl_);
198 }
199 }
200 }
201
202 void
set_all_client_states(remote_subscription_state_e _state)203 remote_subscription::set_all_client_states(remote_subscription_state_e _state) {
204 std::lock_guard<std::mutex> its_lock(mutex_);
205 for (auto &its_item : clients_)
206 its_item.second.first = _state;
207 }
208
209 std::shared_ptr<endpoint_definition>
get_subscriber() const210 remote_subscription::get_subscriber() const {
211 return subscriber_;
212 }
213
214 void
set_subscriber(const std::shared_ptr<endpoint_definition> & _subscriber)215 remote_subscription::set_subscriber(
216 const std::shared_ptr<endpoint_definition> &_subscriber) {
217 subscriber_ = _subscriber;
218 }
219
220 std::shared_ptr<endpoint_definition>
get_reliable() const221 remote_subscription::get_reliable() const {
222 return reliable_;
223 }
224
225 void
set_reliable(const std::shared_ptr<endpoint_definition> & _reliable)226 remote_subscription::set_reliable(
227 const std::shared_ptr<endpoint_definition> &_reliable) {
228 reliable_ = _reliable;
229 }
230
231 std::shared_ptr<endpoint_definition>
get_unreliable() const232 remote_subscription::get_unreliable() const {
233 return unreliable_;
234 }
235
236 void
set_unreliable(const std::shared_ptr<endpoint_definition> & _unreliable)237 remote_subscription::set_unreliable(
238 const std::shared_ptr<endpoint_definition> &_unreliable) {
239 unreliable_ = _unreliable;
240 }
241
242 bool
is_pending() const243 remote_subscription::is_pending() const {
244 std::lock_guard<std::mutex> its_lock(mutex_);
245 for (auto its_client : clients_) {
246 if (its_client.second.first
247 == remote_subscription_state_e::SUBSCRIPTION_PENDING) {
248 return true;
249 }
250 }
251 return false;
252 }
253
254 bool
is_acknowledged() const255 remote_subscription::is_acknowledged() const {
256 std::lock_guard<std::mutex> its_lock(mutex_);
257 for (auto its_client : clients_) {
258 if (its_client.second.first
259 != remote_subscription_state_e::SUBSCRIPTION_ACKED) {
260 return false;
261 }
262 }
263 return true;
264 }
265
266 std::chrono::steady_clock::time_point
get_expiration(const client_t _client) const267 remote_subscription::get_expiration(const client_t _client) const {
268 std::lock_guard<std::mutex> its_lock(mutex_);
269 auto found_client = clients_.find(_client);
270 if (found_client != clients_.end()) {
271 return found_client->second.second;
272 }
273 return std::chrono::steady_clock::now();
274 }
275
276 std::set<client_t>
update(const std::set<client_t> & _clients,const std::chrono::steady_clock::time_point & _timepoint,const bool _is_subscribe)277 remote_subscription::update(const std::set<client_t> &_clients,
278 const std::chrono::steady_clock::time_point &_timepoint,
279 const bool _is_subscribe) {
280 std::set<client_t> its_changed;
281
282 std::lock_guard<std::mutex> its_lock(mutex_);
283 for (const auto &its_client : _clients) {
284 auto found_client = clients_.find(its_client);
285 if (_is_subscribe) {
286 if (found_client != clients_.end()) {
287 found_client->second.second = _timepoint;
288 } else {
289 its_changed.insert(its_client);
290 }
291 } else {
292 if (found_client != clients_.end()) {
293 its_changed.insert(its_client);
294 }
295 }
296 }
297
298 for (const auto &its_client : its_changed) {
299 if (_is_subscribe) {
300 clients_[its_client] = std::make_pair(
301 remote_subscription_state_e::SUBSCRIPTION_PENDING, _timepoint);
302 } else {
303 clients_.erase(its_client);
304 }
305 }
306
307 return its_changed;
308 }
309
310 std::shared_ptr<remote_subscription>
get_parent() const311 remote_subscription::get_parent() const {
312 return parent_.lock();
313 }
314
315 void
set_parent(const std::shared_ptr<remote_subscription> & _parent)316 remote_subscription::set_parent(
317 const std::shared_ptr<remote_subscription> &_parent) {
318 parent_ = _parent;
319 }
320
321 std::uint32_t
get_answers() const322 remote_subscription::get_answers() const {
323 return answers_;
324 }
325
326 void
set_answers(const std::uint32_t _answers)327 remote_subscription::set_answers(const std::uint32_t _answers) {
328 answers_ = _answers;
329 }
330
331 bool
get_ip_address(boost::asio::ip::address & _address) const332 remote_subscription::get_ip_address(boost::asio::ip::address &_address) const {
333 if (reliable_) {
334 _address = reliable_->get_address();
335 return true;
336 }
337 else if (unreliable_) {
338 _address = unreliable_->get_address();
339 return true;
340 }
341 return false;
342 }
343
344 } // namespace vsomeip_v3
345