// Copyright (C) 2014-2017 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/. #ifndef VSOMEIP_V3_ROUTING_MANAGER_PROXY_HPP #define VSOMEIP_V3_ROUTING_MANAGER_PROXY_HPP #include #include #include #include #include #include #include "routing_manager_base.hpp" #include "types.hpp" #include #include namespace vsomeip_v3 { class configuration; class event; class routing_manager_host; class routing_manager_proxy: public routing_manager_base { public: routing_manager_proxy(routing_manager_host *_host, bool _client_side_logging, const std::set > & _client_side_logging_filter); virtual ~routing_manager_proxy(); void init(); void start(); void stop(); std::shared_ptr get_configuration() const; bool offer_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor); void stop_offer_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor); void request_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor); void release_service(client_t _client, service_t _service, instance_t _instance); void subscribe(client_t _client, uid_t _uid, gid_t _gid, service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, event_t _event); void unsubscribe(client_t _client, uid_t _uid, gid_t _gid, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event); bool send(client_t _client, const byte_t *_data, uint32_t _size, instance_t _instance, bool _reliable, client_t _bound_client = VSOMEIP_ROUTING_CLIENT, credentials_t _credentials = {ANY_UID, ANY_GID}, uint8_t _status_check = 0, bool _sent_from_remote = false); bool send_to(const client_t _client, const std::shared_ptr &_target, std::shared_ptr _message); bool send_to(const std::shared_ptr &_target, const byte_t *_data, uint32_t _size, instance_t _instance); void register_event(client_t _client, service_t _service, instance_t _instance, event_t _notifier, const std::set &_eventgroups, const event_type_e _type, reliability_type_e _reliability, std::chrono::milliseconds _cycle, bool _change_resets_cycle, bool _update_on_change, epsilon_change_func_t _epsilon_change_func, bool _is_provided, bool _is_shadow, bool _is_cache_placeholder); void unregister_event(client_t _client, service_t _service, instance_t _instance, event_t _notifier, bool _is_provided); void on_connect(const std::shared_ptr& _endpoint); void on_disconnect(const std::shared_ptr& _endpoint); void on_message(const byte_t *_data, length_t _size, endpoint *_receiver, const boost::asio::ip::address &_destination, client_t _bound_client, credentials_t _credentials, const boost::asio::ip::address &_remote_address, std::uint16_t _remote_port); void on_routing_info(const byte_t *_data, uint32_t _size); void register_client_error_handler(client_t _client, const std::shared_ptr &_endpoint); void handle_client_error(client_t _client); void on_offered_services_info(const byte_t *_data, uint32_t _size); void send_get_offered_services_info(client_t _client, offer_type_e _offer_type); private: void assign_client(); void register_application(); void deregister_application(); void reconnect(const std::unordered_set &_clients); void send_pong() const; void send_offer_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor); void send_release_service(client_t _client, service_t _service, instance_t _instance); void send_register_event(client_t _client, service_t _service, instance_t _instance, event_t _notifier, const std::set &_eventgroups, const event_type_e _type, reliability_type_e _reliability, bool _is_provided); void send_subscribe(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, event_t _event); void send_subscribe_nack(client_t _subscriber, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, remote_subscription_id_t _id); void send_subscribe_ack(client_t _subscriber, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, remote_subscription_id_t _id); bool is_field(service_t _service, instance_t _instance, event_t _event) const; void on_subscribe_nack(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event); void on_subscribe_ack(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event); void cache_event_payload(const std::shared_ptr &_message); void on_stop_offer_service(service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor); void send_pending_commands(); void init_receiver(); void notify_remote_initially(service_t _service, instance_t _instance, eventgroup_t _eventgroup, const std::set &_events_to_exclude); uint32_t get_remote_subscriber_count(service_t _service, instance_t _instance, eventgroup_t _eventgroup, bool _increment); void clear_remote_subscriber_count(service_t _service, instance_t _instance); void assign_client_timeout_cbk(boost::system::error_code const &_error); void register_application_timeout_cbk(boost::system::error_code const &_error); void send_registered_ack(); void set_routing_state(routing_state_e _routing_state) { (void)_routing_state; }; bool is_client_known(client_t _client); bool create_placeholder_event_and_subscribe( service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _notifier, client_t _client); void request_debounce_timeout_cbk(boost::system::error_code const &_error); void send_request_services(std::set& _requests); void send_unsubscribe_ack(service_t _service, instance_t _instance, eventgroup_t _eventgroup, remote_subscription_id_t _id); void resend_provided_event_registrations(); void send_resend_provided_event_response(pending_remote_offer_id_t _id); void send_update_security_policy_response(pending_security_update_id_t _update_id); void send_remove_security_policy_response(pending_security_update_id_t _update_id); void on_update_security_credentials(const byte_t *_data, uint32_t _size); void on_client_assign_ack(const client_t &_client); void on_suspend(); private: enum class inner_state_type_e : std::uint8_t { ST_REGISTERED = 0x0, ST_DEREGISTERED = 0x1, ST_REGISTERING = 0x2, ST_ASSIGNING = 0x3, ST_ASSIGNED = 0x4 }; std::atomic is_connected_; std::atomic is_started_; inner_state_type_e state_; std::shared_ptr sender_; // --> stub std::shared_ptr receiver_; // --> from everybody std::mutex known_clients_mutex_; std::unordered_set known_clients_; std::set pending_offers_; std::set requests_; std::set requests_to_debounce_; struct event_data_t { service_t service_; instance_t instance_; event_t notifier_; event_type_e type_; reliability_type_e reliability_; bool is_provided_; std::set eventgroups_; bool operator<(const event_data_t &_other) const { return std::tie(service_, instance_, notifier_, type_, reliability_, is_provided_, eventgroups_) < std::tie(_other.service_, _other.instance_, _other.notifier_, _other.type_, _other.reliability_, _other.is_provided_, _other.eventgroups_); } }; std::set pending_event_registrations_; std::map> pending_incoming_subscripitons_; std::recursive_mutex incoming_subscriptions_mutex_; std::mutex state_mutex_; std::condition_variable state_condition_; std::map > > remote_subscriber_count_; std::mutex remote_subscriber_count_mutex_; mutable std::mutex sender_mutex_; boost::asio::steady_timer register_application_timer_; std::mutex request_timer_mutex_; boost::asio::steady_timer request_debounce_timer_; bool request_debounce_timer_running_; const bool client_side_logging_; const std::set > client_side_logging_filter_; std::mutex stop_mutex_; }; } // namespace vsomeip_v3 #endif // VSOMEIP_V3_ROUTING_MANAGER_PROXY_HPP_