1 // Copyright (C) 2014-2017 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 #ifndef VSOMEIP_V3_APPLICATION_IMPL_HPP_
7 #define VSOMEIP_V3_APPLICATION_IMPL_HPP_
8 
9 #include <atomic>
10 #include <condition_variable>
11 #include <deque>
12 #include <map>
13 #include <mutex>
14 #include <set>
15 #include <string>
16 #include <thread>
17 #include <vector>
18 
19 #include <boost/asio/signal_set.hpp>
20 #include <boost/asio/steady_timer.hpp>
21 
22 #include <vsomeip/export.hpp>
23 #include <vsomeip/application.hpp>
24 
25 #ifdef ANDROID
26 #include "../../configuration/include/internal_android.hpp"
27 #else
28 #include "../../configuration/include/internal.hpp"
29 #endif // ANDROID
30 #include "../../routing/include/routing_manager_host.hpp"
31 
32 namespace vsomeip_v3 {
33 
34 class runtime;
35 class configuration;
36 class routing_manager;
37 class routing_manager_stub;
38 
39 class application_impl: public application,
40         public routing_manager_host,
41         public std::enable_shared_from_this<application_impl> {
42 public:
43     VSOMEIP_EXPORT application_impl(const std::string &_name);
44     VSOMEIP_EXPORT  ~application_impl();
45 
46     VSOMEIP_EXPORT bool init();
47     VSOMEIP_EXPORT void start();
48     VSOMEIP_EXPORT void stop();
49     VSOMEIP_EXPORT void process(int _number);
50 
51     VSOMEIP_EXPORT security_mode_e get_security_mode() const;
52 
53     // Provide services / events
54     VSOMEIP_EXPORT void offer_service(service_t _service, instance_t _instance,
55             major_version_t _major, minor_version_t _minor);
56 
57     VSOMEIP_EXPORT void stop_offer_service(service_t _service, instance_t _instance,
58             major_version_t _major, minor_version_t _minor);
59 
60     VSOMEIP_EXPORT void offer_event(service_t _service, instance_t _instance,
61             event_t _notifier,
62             const std::set<eventgroup_t> &_eventgroups, event_type_e _type,
63             std::chrono::milliseconds _cycle, bool _change_resets_cycle,
64             bool _update_on_change,
65             const epsilon_change_func_t &_epsilon_change_func,
66             reliability_type_e _reliability);
67 
68     VSOMEIP_EXPORT void stop_offer_event(service_t _service,
69             instance_t _instance, event_t _event);
70 
71     // Consume services / events
72     VSOMEIP_EXPORT void request_service(
73             service_t _service, instance_t _instance,
74             major_version_t _major, minor_version_t _minor);
75     VSOMEIP_EXPORT void release_service(
76             service_t _service, instance_t _instance);
77 
78     VSOMEIP_EXPORT void request_event(service_t _service,
79             instance_t _instance, event_t _event,
80             const std::set<eventgroup_t> &_eventgroups,
81             event_type_e _type, reliability_type_e _reliability);
82     VSOMEIP_EXPORT void release_event(service_t _service,
83             instance_t _instance, event_t _event);
84 
85     VSOMEIP_EXPORT void subscribe(service_t _service, instance_t _instance,
86             eventgroup_t _eventgroup, major_version_t _major, event_t _event);
87 
88     VSOMEIP_EXPORT void unsubscribe(service_t _service, instance_t _instance,
89             eventgroup_t _eventgroup);
90     VSOMEIP_EXPORT void unsubscribe(service_t _service, instance_t _instance,
91             eventgroup_t _eventgroup, event_t _event);
92 
93     VSOMEIP_EXPORT bool is_available(service_t _service, instance_t _instance,
94             major_version_t _major, minor_version_t _minor) const;
95 
96     VSOMEIP_EXPORT void send(std::shared_ptr<message> _message);
97 
98     VSOMEIP_EXPORT void notify(service_t _service, instance_t _instance,
99             event_t _event, std::shared_ptr<payload> _payload,
100             bool _force) const;
101 
102     VSOMEIP_EXPORT void notify_one(service_t _service, instance_t _instance,
103             event_t _event, std::shared_ptr<payload> _payload, client_t _client,
104             bool _force) const;
105 
106     VSOMEIP_EXPORT void register_state_handler(state_handler_t _handler);
107     VSOMEIP_EXPORT void unregister_state_handler();
108 
109     VSOMEIP_EXPORT void register_message_handler(service_t _service,
110             instance_t _instance, method_t _method, message_handler_t _handler);
111     VSOMEIP_EXPORT void unregister_message_handler(service_t _service,
112             instance_t _instance, method_t _method);
113 
114     VSOMEIP_EXPORT void register_availability_handler(service_t _service,
115             instance_t _instance, availability_handler_t _handler,
116             major_version_t _major, minor_version_t _minor);
117     VSOMEIP_EXPORT void unregister_availability_handler(service_t _service,
118             instance_t _instance,
119             major_version_t _major, minor_version_t _minor);
120 
121     VSOMEIP_EXPORT void register_subscription_handler(service_t _service,
122             instance_t _instance, eventgroup_t _eventgroup, subscription_handler_t _handler);
123     VSOMEIP_EXPORT void unregister_subscription_handler(service_t _service,
124                 instance_t _instance, eventgroup_t _eventgroup);
125 
126     VSOMEIP_EXPORT bool is_routing() const;
127 
128     // routing_manager_host
129     VSOMEIP_EXPORT const std::string & get_name() const;
130     VSOMEIP_EXPORT client_t get_client() const;
131     VSOMEIP_EXPORT void set_client(const client_t &_client);
132     VSOMEIP_EXPORT session_t get_session();
133     VSOMEIP_EXPORT diagnosis_t get_diagnosis() const;
134     VSOMEIP_EXPORT std::shared_ptr<configuration> get_configuration() const;
135     VSOMEIP_EXPORT std::shared_ptr<configuration_public> get_public_configuration() const;
136     VSOMEIP_EXPORT boost::asio::io_service & get_io();
137 
138     VSOMEIP_EXPORT void on_state(state_type_e _state);
139     VSOMEIP_EXPORT void on_availability(service_t _service, instance_t _instance,
140             bool _is_available, major_version_t _major, minor_version_t _minor);
141     VSOMEIP_EXPORT void on_message(std::shared_ptr<message> &&_message);
142     VSOMEIP_EXPORT void on_subscription(service_t _service, instance_t _instance,
143             eventgroup_t _eventgroup, client_t _client, uid_t _uid, gid_t _gid, bool _subscribed,
144             std::function<void(bool)> _accepted_cb);
145     VSOMEIP_EXPORT void on_subscription_status(service_t _service, instance_t _instance,
146             eventgroup_t _eventgroup, event_t _event, uint16_t _error);
147     VSOMEIP_EXPORT void register_subscription_status_handler(service_t _service,
148             instance_t _instance, eventgroup_t _eventgroup, event_t _event,
149             subscription_status_handler_t _handler, bool _is_selective);
150     VSOMEIP_EXPORT void unregister_subscription_status_handler(service_t _service,
151                 instance_t _instance, eventgroup_t _eventgroup, event_t _event);
152 
153     // service_discovery_host
154     VSOMEIP_EXPORT routing_manager * get_routing_manager() const;
155 
156     VSOMEIP_EXPORT bool are_available(available_t &_available,
157                        service_t _service, instance_t _instance,
158                        major_version_t _major, minor_version_t _minor) const;
159     VSOMEIP_EXPORT void set_routing_state(routing_state_e _routing_state);
160 
161     VSOMEIP_EXPORT void clear_all_handler();
162 
163 
164     VSOMEIP_EXPORT void get_offered_services_async(offer_type_e _offer_type, offered_services_handler_t _handler);
165 
166     VSOMEIP_EXPORT void on_offered_services_info(std::vector<std::pair<service_t, instance_t>> &_services);
167 
168     VSOMEIP_EXPORT void set_watchdog_handler(watchdog_handler_t _handler, std::chrono::seconds _interval);
169 
170     VSOMEIP_EXPORT void register_async_subscription_handler(service_t _service,
171             instance_t _instance, eventgroup_t _eventgroup, async_subscription_handler_t _handler);
172 
173     VSOMEIP_EXPORT void set_sd_acceptance_required(const remote_info_t& _remote,
174                                                    const std::string& _path, bool _enable);
175     VSOMEIP_EXPORT void set_sd_acceptance_required(
176             const sd_acceptance_map_type_t& _remotes, bool _enable);
177 
178     VSOMEIP_EXPORT sd_acceptance_map_type_t get_sd_acceptance_required();
179 
180     VSOMEIP_EXPORT void register_sd_acceptance_handler(sd_acceptance_handler_t _handler);
181 
182     VSOMEIP_EXPORT void register_reboot_notification_handler(reboot_notification_handler_t _handler);
183 
184     VSOMEIP_EXPORT void register_routing_ready_handler(routing_ready_handler_t _handler);
185     VSOMEIP_EXPORT void register_routing_state_handler(routing_state_handler_t _handler);
186 
187     VSOMEIP_EXPORT bool update_service_configuration(service_t _service,
188                                                      instance_t _instance,
189                                                      std::uint16_t _port,
190                                                      bool _reliable,
191                                                      bool _magic_cookies_enabled,
192                                                      bool _offer);
193 
194     VSOMEIP_EXPORT void update_security_policy_configuration(uint32_t _uid,
195                                                              uint32_t _gid,
196                                                              std::shared_ptr<policy> _policy,
197                                                              std::shared_ptr<payload> _payload,
198                                                              security_update_handler_t _handler);
199     VSOMEIP_EXPORT void remove_security_policy_configuration(uint32_t _uid,
200                                                              uint32_t _gid,
201                                                              security_update_handler_t _handler);
202 
203 private:
204     //
205     // Types
206     //
207 
208     enum class handler_type_e : uint8_t {
209         MESSAGE,
210         AVAILABILITY,
211         STATE,
212         SUBSCRIPTION,
213         OFFERED_SERVICES_INFO,
214         WATCHDOG,
215         UNKNOWN
216     };
217 
218     struct sync_handler {
219 
sync_handlervsomeip_v3::application_impl::sync_handler220         sync_handler(std::function<void()> _handler) :
221                     handler_(_handler),
222                     service_id_(ANY_SERVICE),
223                     instance_id_(ANY_INSTANCE),
224                     method_id_(ANY_METHOD),
225                     session_id_(0),
226                     eventgroup_id_(0),
227                     handler_type_(handler_type_e::UNKNOWN) { }
228 
sync_handlervsomeip_v3::application_impl::sync_handler229         sync_handler(service_t _service_id, instance_t _instance_id,
230                      method_t _method_id, session_t _session_id,
231                      eventgroup_t _eventgroup_id, handler_type_e _handler_type) :
232                     handler_(nullptr),
233                     service_id_(_service_id),
234                     instance_id_(_instance_id),
235                     method_id_(_method_id),
236                     session_id_(_session_id),
237                     eventgroup_id_(_eventgroup_id),
238                     handler_type_(_handler_type) { }
239 
240         std::function<void()> handler_;
241         service_t service_id_;
242         instance_t instance_id_;
243         method_t method_id_;
244         session_t session_id_;
245         eventgroup_t eventgroup_id_;
246         handler_type_e handler_type_;
247     };
248 
249     struct message_handler {
message_handlervsomeip_v3::application_impl::message_handler250         message_handler(message_handler_t _handler) :
251             handler_(_handler) {}
252 
operator <vsomeip_v3::application_impl::message_handler253         bool operator<(const message_handler& _other) const {
254             return handler_.target<void (*)(const std::shared_ptr<message> &)>()
255                     < _other.handler_.target<void (*)(const std::shared_ptr<message> &)>();
256         }
257         message_handler_t handler_;
258     };
259 
260     //
261     // Methods
262     //
263     bool is_available_unlocked(service_t _service, instance_t _instance,
264                                major_version_t _major, minor_version_t _minor) const;
265 
266     bool are_available_unlocked(available_t &_available,
267                                 service_t _service, instance_t _instance,
268                                 major_version_t _major, minor_version_t _minor) const;
269     void do_register_availability_handler(service_t _service,
270             instance_t _instance, availability_handler_t _handler,
271             major_version_t _major, minor_version_t _minor);
272 
273 
274     void main_dispatch();
275     void dispatch();
276     void invoke_handler(std::shared_ptr<sync_handler> &_handler);
277     std::shared_ptr<sync_handler> get_next_handler();
278     void reschedule_availability_handler(const std::shared_ptr<sync_handler> &_handler);
279     bool has_active_dispatcher();
280     bool is_active_dispatcher(const std::thread::id &_id);
281     void remove_elapsed_dispatchers();
282 
283     void shutdown();
284 
285     void send_back_cached_event(service_t _service, instance_t _instance, event_t _event);
286     void send_back_cached_eventgroup(service_t _service, instance_t _instance, eventgroup_t _eventgroup);
287     void check_send_back_cached_event(service_t _service, instance_t _instance,
288                                       event_t _event, eventgroup_t _eventgroup,
289                                       bool *_send_back_cached_event,
290                                       bool *_send_back_cached_eventgroup);
291     void remove_subscription(service_t _service, instance_t _instance,
292                              eventgroup_t _eventgroup, event_t _event);
293     bool check_for_active_subscription(service_t _service, instance_t _instance,
294                                        event_t _event);
295 
296     void deliver_subscription_state(service_t _service, instance_t _instance,
297             eventgroup_t _eventgroup, event_t _event, uint16_t _error);
298 
299     bool check_subscription_state(service_t _service, instance_t _instance,
300             eventgroup_t _eventgroup, event_t _event);
301 
302     void print_blocking_call(const std::shared_ptr<sync_handler>& _handler);
303 
304     void watchdog_cbk(boost::system::error_code const &_error);
305 
306     //
307     // Attributes
308     //
309     std::shared_ptr<runtime> runtime_;
310     std::atomic<client_t> client_; // unique application identifier
311     session_t session_;
312     std::mutex session_mutex_;
313 
314     std::mutex initialize_mutex_;
315     bool is_initialized_;
316 
317     std::string name_;
318     std::shared_ptr<configuration> configuration_;
319 
320     boost::asio::io_service io_;
321     std::set<std::shared_ptr<std::thread> > io_threads_;
322     std::shared_ptr<boost::asio::io_service::work> work_;
323 
324     // Proxy to or the Routing Manager itself
325     std::shared_ptr<routing_manager> routing_;
326 
327     // vsomeip state (registered / deregistered)
328     state_type_e state_;
329 
330     // vsomeip state handler
331     std::mutex state_handler_mutex_;
332     state_handler_t handler_;
333 
334     // vsomeip security mode
335     security_mode_e security_mode_;
336 
337     // vsomeip offered services handler
338     std::mutex offered_services_handler_mutex_;
339     offered_services_handler_t offered_services_handler_;
340 
341     // Method/Event (=Member) handlers
342     std::map<service_t,
343             std::map<instance_t, std::map<method_t, message_handler_t> > > members_;
344     mutable std::mutex members_mutex_;
345 
346     // Availability handlers
347     typedef std::map<major_version_t, std::map<minor_version_t, std::pair<availability_handler_t,
348             bool>>> availability_major_minor_t;
349     std::map<service_t, std::map<instance_t, availability_major_minor_t>> availability_;
350     mutable std::recursive_mutex availability_mutex_;
351 
352     // Availability
353     mutable available_t available_;
354 
355     // Subscription handlers
356     std::map<service_t,
357             std::map<instance_t,
358                     std::map<eventgroup_t,
359                             std::pair<subscription_handler_t, async_subscription_handler_t>>>> subscription_;
360     mutable std::mutex subscription_mutex_;
361     std::map<service_t,
362         std::map<instance_t, std::map<eventgroup_t,
363         std::map<client_t, error_handler_t > > > > eventgroup_error_handlers_;
364     mutable std::mutex subscription_error_mutex_;
365 
366 #ifdef VSOMEIP_ENABLE_SIGNAL_HANDLING
367     // Signals
368     boost::asio::signal_set signals_;
369     bool catched_signal_;
370 #endif
371 
372     // Handlers
373     mutable std::deque<std::shared_ptr<sync_handler>> handlers_;
374     mutable std::mutex handlers_mutex_;
375 
376     // Dispatching
377     std::atomic<bool> is_dispatching_;
378     // Dispatcher threads
379     std::map<std::thread::id, std::shared_ptr<std::thread>> dispatchers_;
380     // Dispatcher threads that elapsed and can be removed
381     std::set<std::thread::id> elapsed_dispatchers_;
382     // Dispatcher threads that are running
383     std::set<std::thread::id> running_dispatchers_;
384     // Mutex to protect access to dispatchers_ & elapsed_dispatchers_
385     std::mutex dispatcher_mutex_;
386 
387     // Condition to wakeup the dispatcher thread
388     mutable std::condition_variable dispatcher_condition_;
389     std::size_t max_dispatchers_;
390     std::size_t max_dispatch_time_;
391 
392     std::condition_variable stop_cv_;
393     std::mutex start_stop_mutex_;
394     bool stopped_;
395     std::thread stop_thread_;
396 
397     std::condition_variable block_stop_cv_;
398     std::mutex block_stop_mutex_;
399     bool block_stopping_;
400 
401     static uint32_t app_counter__;
402     static std::mutex app_counter_mutex__;
403 
404     bool is_routing_manager_host_;
405 
406     // Event subscriptions
407     std::mutex subscriptions_mutex_;
408     std::map<service_t, std::map<instance_t,
409             std::map<event_t, std::map<eventgroup_t, bool>>>> subscriptions_;
410 
411     std::thread::id stop_caller_id_;
412     std::thread::id start_caller_id_;
413 
414     bool stopped_called_;
415 
416     std::map<service_t, std::map<instance_t, std::map<eventgroup_t,
417             std::map<event_t, std::pair<subscription_status_handler_t, bool> > > > > subscription_status_handlers_;
418     std::mutex subscription_status_handlers_mutex_;
419 
420     std::mutex subscriptions_state_mutex_;
421     std::map<std::tuple<service_t, instance_t, eventgroup_t, event_t>,
422         subscription_state_e> subscription_state_;
423 
424     std::mutex watchdog_timer_mutex_;
425     boost::asio::steady_timer watchdog_timer_;
426     watchdog_handler_t watchdog_handler_;
427     std::chrono::seconds watchdog_interval_;
428 
429     bool client_side_logging_;
430     std::set<std::tuple<service_t, instance_t> > client_side_logging_filter_;
431 
432     std::map<std::pair<service_t, instance_t>,
433             std::deque<std::shared_ptr<sync_handler> > > availability_handlers_;
434 
435     uid_t own_uid_;
436     gid_t own_gid_;
437 
438 #ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG
439     bool has_session_handling_;
440 #endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG
441 };
442 
443 } // namespace vsomeip_v3
444 
445 #endif // VSOMEIP_V3_APPLICATION_IMPL_HPP_
446