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